Uso di Git e Perforce: flusso di lavoro di integrazione
Scenario: il tuo team lavora in modo indipendente su un repository Git, ma una parte dell'organizzazione utilizza ancora Perforce per gestire parti della stessa base di codice. Questi team che usano Perforce non hanno intenzione di passare a Git, mentre invece il tuo team lo ha già fatto (per molte buone ragioni). È importante poter mantenere attivo un processo di condivisione del codice bidirezionale tra le basi di codice in modo da condividere i miglioramenti sviluppati in entrambe le versioni, nella migliore delle ipotesi senza impiegare troppo tempo o impantanare eccessivamente il team.
È qui che entra in gioco questa guida. In TomTom questa operazione di sincronizzazione viene eseguita una volta per ogni nuovo rilascio, cosa che nel caso dell'azienda avviene una volta ogni mese e mezzo.
-- Questo post è stato scritto in collaborazione con Andrea Carlevato, Adolfo Bulfoni e Krzysztof Karczewski, che sono stati così gentili da condividere il processo Git utilizzato nell'unità NavApps di TomTom. --
Presupposti iniziali
Supponiamo che tu abbia già familiarità con l'utilizzo di base di git e con il flusso di lavoro dei branch di funzioni. In caso contrario, prenditi il tempo per guardare un tutorial pratico o per seguire un webinar. Torna qui quando avrai finito, ti aspettiamo.
Dal momento che ci sono alcune sottigliezze da tenere a mente durante il processo, suggeriamo di fare molta attenzione quando si eseguono queste integrazioni. Iniziamo quando vuoi!
Installazione di git p4
Il primo passo consiste nell'installazione del bridge. Controlla se lo hai già installato digitando quanto segue nella riga di comando:
git p4
Se il sistema segnala che git p4
non è installato, scarica git-p4.py e inseriscilo in una cartella in PATH
, ad esempio ~/bin
, (ovviamente è necessario che sia installato anche Python perché questo procedimento funzioni).
Rendilo eseguibile con:
chmod +x git-p4.py
Modifica il file ~/.gitconfig
aggiungendo:
[alias]
p4 = !~/bin/bit-p4.py
Quindi esegui di nuovo git p4
. A questo punto, non dovresti ricevere errori. Lo strumento è installato.
materiale correlato
Come spostare un repository Git completo
Scopri la soluzione
Impara a utilizzare Git con Bitbucket Cloud
Panoramica del flusso di lavoro
Clonazione iniziale
Poiché i progetti in P4
possono accumulare una cronologia di enormi dimensioni, il team può scegliere un punto limite da cui far partire la sincronizzazione, risparmiando molto spazio e tempo. git p4
consente di scegliere la lista delle modifiche da cui iniziare il monitoraggio:
git p4 clone //depot/path/project@<earlier-cutoff-point>,<latest-changelist>
- Adesso possiamo eseguire una sincronizzazione e verificare di aver ricevuto tutti i set di modifiche a livello locale:
git p4 sync
Il comando sync
rileva nuove modifiche in P4
e le importa come commit Git.
- Assegniamo un nome al branch che useremo per interagire direttamente con
p4-integ
di Perforce. A questo punto vogliamo solo creare un branch daremotes/p4/main
:
git checkout -b p4-integ origin/p4/main
Sincronizzazione rapida di follow-up (ovvero "bait and switch")
Dopo che la prima importazione è stata completata, le successive sincronizzazioni git->p4
possono essere eseguite con i seguenti comandi:
git checkout p4-integ
git p4 sync
Il processo riportato sopra funziona, anche se può essere lento. Un modo molto più veloce per eseguire la sincronizzazione consiste nel ricreare riferimenti (refs
) identici a quelli utilizzati nell'ultima integrazione. Questo è anche un ottimo modo per assicurarsi che i nuovi sviluppatori incaricati dell'integrazione partano dalla lista di commit/modifiche giusta.
Ecco come fare:
- Rimuovi i
refs
meno recenti originali (oppure obsoleti) relativi alp4
remoto (facoltativo):
git symbolic-ref -d refs/remotes/p4/HEAD
git update-ref -d refs/remotes/p4/main
- Crea riferimenti artificiali (ovvero finti) remoti che puntano all'ultimo commit su
p4-integ
suorigin
:
git update-ref refs/remotes/p4/main remotes/origin/p4-integ
git symbolic-ref refs/remotes/p4/HEAD refs/remotes/p4/main
L'unico inconveniente di questa sincronizzazione molto più rapida è che occorre specificare esplicitamente il branch in git p4
. Quindi ecco il comando finale:
git p4 sync --branch=refs/remotes/p4/main
Il modo in cui git p4
monitora la mappatura tra gli ID dei commit git e di P4 è tramite l'annotazione dei commit con metadati:
Merge pull request #340 in MOB/project from bugfix/PRJ-3185 to develop
Squashed commit of the following:
commit c2843b424fb3f5be1ba64be51363db63621162b4
Author: Some Developer
Date: Wed Jan 14 09:26:45 2015 +0100
[PRJ-3185] The app shows ...
commit abc135fc1fccf74dac8882d70b1ddd8a4750f078
Author: Some Developer
Date: Tue Jan 13 14:18:46 2015 +0100
[PRJ-3185] The app shows the rating ...
[git-p4: depot-paths = "//depot-mobile/project/": change = 1794239]
Ricorda che in una versione più recente di git p4
i metadati per associare un commit git a una lista delle modifiche di P4
vengono archiviati in una nota di commit e non nel messaggio di commit. Il team di TomTom non ha apprezzato questo cambiamento perché richiedeva un po' più di lavoro per controllare i numeri della lista delle modifiche quando necessario.
Trasferimento delle modifiche da git a Perforce
Dopo aver completato l'operazione di sincronizzazione rapida descritta sopra, puoi eseguire il push delle modifiche da git
a Perforce.
Il primo passo consiste nella riassegnazione di p4-integ
con le modifiche provenienti da remotes/p4/main
:
git checkout p4-integ
git p4 rebase
Dopodiché, tutte le nuove modifiche provenienti da Perforce dovrebbero trovarsi in p4-integ
, per poter aggiornare main
:
- Quindi, puoi semplicemente eseguire:
git checkout main
git merge develop
- Assicurati di disporre dei tag più recenti a livello locale:
git fetch --tags
- Usa una pulizia (
cleanup
) temporanea nel caso in cui occorra rimuovere i commit già inP4
(vedi il tagP4
nel commit). Nel caso in cui nessun commit debba essere saltato, usa una riassegnazione automatica che linearizzerà la cronologia:
git checkout -b cleanup #branching off from main
git rebase -s recursive -X theirs tag/last-p4-integ
- Tramite una riassegnazione interattiva, puoi ottenere lo stesso risultato con:
git rebase -i tag/last-p4-integ
- Usa
cherry-pick
per scegliere i nuovi commit e inserirli nel branchp4-integ
. Procediamo in questo modo perché non diamo per scontato che i branchgit
main
edevelop
possano essere conservati come veri e propri predecessori del branchp4-integ
. In effetti in TomTom non è più così.
git checkout p4-integ
git cherry-pick tag/last-p4-integ..cleanup
- Invia a
P4
e sincronizzap4-integ
:
git p4 submit
git p4 sync --branch=refs/remotes/p4/main
git reset --hard refs/remotes/p4/main
- Elimina il branch di riassegnazione temporaneo:
git branch -D cleanup
- Rimuovi il puntatore al punto di integrazione (tag) più recente a livello locale e in remoto:
git tag -d tag/last-p4-integ
git push origin :refs/tags/tag/last-p4-integ
- Aggiorna il tag
last-p4-integ
in modo che punti al nuovo punto di integrazione inP4
:
git checkout develop
git tag -a tag/last-p4-integ -m "tag pointer to last develop commit integrated with p4"
git push origin main
git push origin tag/last-p4-integ
git push origin p4-integ
Esegui i test sulla base di codice P4
per verificare che l'integrazione non abbia introdotto problemi.
Trasferimento delle modifiche da Perforce a git
Questo processo dovrebbe essere eseguito in seguito al push git-> P4
. Dopo che i test vengono superati correttamente su P4
, è possibile spostare le modifiche da P4
a git
con il comando seguente:
git checkout p4-integ
git p4 sync --branch=refs/remotes/p4/main
git p4 rebase
- Di seguito è riportato un trucchetto per mettere in pratica una solida strategia di merge "theirs" che consente di eseguire lo squash delle modifiche in arrivo in un unico commit. Eccolo qui:
git checkout -b p4mergebranch #branching off from p4-integ
git merge -s ours main ## ignoring all changes from main
git checkout main
git merge p4mergebranch --squash
git commit -m "Type your integration message"
git branch -D p4mergebranch
- Una volta completato il passaggio sopra, esegui il merge delle modifiche in
develop
:
<p>Bitbucket has the following space stations:</p>
<p>
<b>Earth's Moon</b><br>
Headquarters
</p>
Poiché potrebbero esserci stati dei cambiamenti da quando abbiamo selezionato le modifiche da develop
, potrebbe essere necessario prima eseguirne un merge. È importante, tuttavia, aggiornare il tag last-p4-integ
al commit corretto, soprattutto diverso dal commit di merge nel branch di sviluppo. Per procedere in modo sicuro, è meglio taggare lo stato corrente di main
:
- Rimuovi il tag meno recente in locale e in remoto:
git tag -d tag/last-p4-integ
git push origin :refs/tags/tag/last-p4-integ
- Crea un tag nella nuova posizione:
git checkout main
git tag -a tag/last-p4-integ -m "tag pointer to last develop commit integrated with p4"
- Ora esegui il push di
main, develop, p4-integ
etag/last-p4-integ
inorigin
:
Conclusioni
Ecco quindi come eseguire la sincronizzazione di due team di sviluppo attivi che utilizzano Git e Perforce. Il processo descritto sopra si è evoluto nel tempo in TomTom e ora funziona senza grossi problemi da parecchio tempo. Questo processo è valido, ma la sua gestione implica un certo sovraccarico. Se ne hai la possibilità, ti consigliamo di eseguire la migrazione completa a Git.
Ad ogni modo, se segui un approccio diverso per gestire la sincronizzazione bidirezionale, mi piacerebbe molto conoscerlo nei commenti qui sotto. Oppure invia un tweet a @durdn o ad @atlassiandev.
Grazie ancora ad Andrea Carlevato, Adolfo Bulfoni e Krzysztof Karczewski.
Condividi l'articolo
Argomento successivo
Letture consigliate
Aggiungi ai preferiti queste risorse per ricevere informazioni sui tipi di team DevOps e aggiornamenti continui su DevOps in Atlassian.