Werken met Git en Perforce: integratieworkflow
Dus dit is het scenario: je team werkt onafhankelijk aan een Git-repository, maar een deel van de organisatie gebruikt nog steeds Perforce om delen van dezelfde codebase te beheren. De teams die Perforce gebruiken, zijn niet van plan om te migreren, maar jouw team is al overgestapt op Git (om talloze goede redenen). Het is belangrijk om het deelproces van code in twee richtingen te blijven garanderen, zodat verbeteringen aan beide versies gedeeld kunnen worden, en dat hopelijk zonder teveel tijd te kosten of je team dwars te zitten.
Hier komt deze handleiding van pas. Bij TomTom wordt deze synchronisatie eenmaal per nieuwe release uitgevoerd, wat in hun geval eens in de anderhalve maand betekent.
-- Dit bericht is geschreven in samenwerking met Andrea Carlevato, Adolfo Bulfoni en Krzysztof Karczewski, die zo vriendelijk waren om het Git-proces te delen dat werd gebruikt bij de NavApps-eenheid van TomTom. --
Veronderstellingen voordat we beginnen
We gaan ervan uit dat je al bekend bent met het basisgebruik van git en bekend bent met een workflow voor functiebranches. Zo niet, neem dan de tijd om een praktische tutorial of een webinar te bekijken. Kom terug als je klaar bent, wij wachten wel op je.
Omdat er wat subtiel onderscheid is waarmee je rekening moet houden tijdens het proces, raden we aan heel voorzichtig te zijn bij het uitvoeren van deze integraties. Laten we er dieper in duiken als je er klaar voor bent!
git p4 installeren
De eerste stap is het installeren van de koppeling. Controleer of je deze al hebt geïnstalleerd door deze opdrachtregel te typen:
git p4
Als het systeem klaagt dat git p4
niet is geïnstalleerd, download dan git-p4.py en zet het in een map op je PATH
, bijvoorbeeld ~/bin
(natuurlijk moet Python ook geïnstalleerd zijn).
Maak het uitvoerbaar met:
chmod +x git-p4.py
Bewerk het ~/.gitconfig
-bestand door het volgende toe te voegen:
[alias]
p4 = !~/bin/bit-p4.py
Voer dan git p4
opnieuw uit en je zou geen fouten moeten krijgen. De tool is geïnstalleerd.
gerelateerd materiaal
Een volledige Git-repository verplaatsen
Oplossing bekijken
Git leren met Bitbucket Cloud
Overzicht van de workflow
Eerste kloon
Omdat projecten in P4
een enorme geschiedenis kunnen verzamelen, kan het team een tussenpunt kiezen om vanaf te synchroniseren, wat veel ruimte en tijd bespaart. git p4
biedt je de mogelijkheid om de lijst met wijzigingen te kiezen waarvandaan je begint met traceren:
git p4 clone //depot/path/project@<earlier-cutoff-point>,<latest-changelist>
- Nu kunnen we een synchronisatie uitvoeren en controleren of we alle changesets lokaal hebben ontvangen:
git p4 sync
De opdracht sync
vindt nieuwe wijzigingen in P4
en importeert deze als Git-commits.
- We noemen de branch die we zullen gebruiken om rechtstreeks te communiceren met Perforce
p4-integ
. Op dit moment willen we er gewoon vertakken vanremotes/p4/main
:
git checkout -b p4-integ origin/p4/main
Snelle vervolgsynchronisatie (oftewel 'de wisseltruc')
Nadat de eerste import is voltooid, kunnen de daaropvolgende git->p4
-synchronisaties worden uitgevoerd met de volgende opdrachten:
git checkout p4-integ
git p4 sync
Het bovenstaande werkt, maar het kan traag zijn. Een veel snellere manier om de synchronisatie uit te voeren, is door dezelfde refs
aan te maken als degene die in de nieuwste integratie zijn gebruikt. Dit is ook een handige manier om ervoor te zorgen dat elke nieuwe ontwikkelaar die met de integratie wordt belast, op de juiste lijst met commits/wijzigingen begint.
Dit is hoe je dat aanpakt:
- Verwijder de oude originele (of verouderde)
refs
voor de remotep4
(optioneel):
git symbolic-ref -d refs/remotes/p4/HEAD
git update-ref -d refs/remotes/p4/main
- Maak kunstmatige (ook wel valse) remote refs aan die verwijzen naar de laatste commit op
p4-integ
inorigin
:
git update-ref refs/remotes/p4/main remotes/origin/p4-integ
git symbolic-ref refs/remotes/p4/HEAD refs/remotes/p4/main
Het enige nadeel van deze veel snellere synchronisatie is dat we expliciet de branch in git p4
moeten specificeren. Dus hier is de laatste opdracht:
git p4 sync --branch=refs/remotes/p4/main
De manier waarop git p4
de toewijzing volgt tussen git commit-ID's en P4's is door commits te voorzien van metagegevens:
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]
Merk op dat in een recentere versie van git p4
de metagegevens om een git-commit te koppelen aan een wijzigingslijst van P4
worden opgeslagen in een commit-notitie en niet in het commit-bericht. Het TomTom-team was niet blij met de wijziging, omdat het daardoor iets lastiger werd om de nummers van de wijzigingslijst te controleren wanneer dat nodig was.
Veranderingen overzetten van git naar Perforce
Nadat de snelle synchronisatie hierboven is voltooid, ben je nu klaar om wijzigingen van git
naar Perforce te pushen.
De eerste stap is om p4-integ te rebasen
met wijzigingen afkomstig uit remotes/p4/main
:
git checkout p4-integ
git p4 rebase
Hierna zouden alle nieuwe wijzigingen ten opzichte van Perforce op p4-integ
moeten staan, zodat we main
kunnen updaten:
- Daarna kun je gewoon het volgende uitvoeren:
git checkout main
git merge develop
- Zorg ervoor dat je de laatste tags lokaal hebt:
git fetch --tags
- Gebruik een tijdelijke
cleanup
voor het geval je commits moet verwijderen die al inP4
staan (zieP4
-tag in commit). In het geval dat er geen commits overgeslagen moeten worden, gebruik je een automatische rebase die de geschiedenis zal lineariseren:
git checkout -b cleanup #branching off from main
git rebase -s recursive -X theirs tag/last-p4-integ
- Met behulp van een interactieve rebase kan dit in plaats daarvan worden gedaan met:
git rebase -i tag/last-p4-integ
- Gebruik
cherry-pick
om de nieuwe commits te kiezen en ze op de branchp4-integ
te zetten. We doen het op deze manier omdat we er niet van uitgaan dat degit
-branchesmain
endevelop
bewaard kunnen worden als echte voorouders van dep4-integ
-branch. Bij TomTom is dit in feite niet meer het geval.
git checkout p4-integ
git cherry-pick tag/last-p4-integ..cleanup
- Verstuur naar
P4
en synchroniseerp4-integ
:
git p4 submit
git p4 sync --branch=refs/remotes/p4/main
git reset --hard refs/remotes/p4/main
- Verwijder de tijdelijke rebase-branch:
git branch -D cleanup
- Verwijder de pointer naar het laatste integratiepunt (tag), lokaal en remote:
git tag -d tag/last-p4-integ
git push origin :refs/tags/tag/last-p4-integ
- Update de tag
last-p4-integ
om naar het nieuwe integratiepunt inP4
te verwijzen:
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
Voer tests uit opde codebase van P4
om te controleren of de integratie geen problemen opleverde.
Wijzigingen overzetten van Perforce naar Git
Dit zou moeten gebeuren nadat de git->P4
-push al is uitgevoerd. Nadat de tests zijn geslaagd op P4
, kunnen we nu de wijzigingen van P4
naar git
overzetten met het volgende:
git checkout p4-integ
git p4 sync --branch=refs/remotes/p4/main
git p4 rebase
- Het volgende taak is een kleine truc om 'hun' samenvoegingsstrategie robuust uit te voeren, door de binnenkomende wijzigingen samen te voegen tot één enkele commit. Dus daar gaat 'ie:
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
- Als we klaar zijn met het bovenstaande, voeg je de wijzigingen samen met
develop
:
<p>Bitbucket has the following space stations:</p>
<p>
<b>Earth's Moon</b><br>
Headquarters
</p>
Aangezien er misschien wat veranderingen zijn opgetreden sinds we voor wijzigingen uit develop
hebben gehaald, is het misschien nodig om ze eerst samen te voegen. Het is echter belangrijk om de tag last-p4-integ
te updaten naar de juiste commit, vooral niet de commit die met develop moet worden samengevoegd. Om dit op een veilige manier te doen, is het het beste om de huidige status van de main
te taggen:
- Verwijder de oude tag lokaal en remote:
git tag -d tag/last-p4-integ
git push origin :refs/tags/tag/last-p4-integ
- Tags aanmaken op een nieuwe positie:
git checkout main
git tag -a tag/last-p4-integ -m "tag pointer to last develop commit integrated with p4"
- Push nu
main, develop, p4-integ
entag/last-p4-integ
naarorigin
:
Conclusies
Dus zo synchroniseer je tussen twee actieve ontwikkelingsteams via Git en Perforce. Bovenstaand proces is in de loop der tijd geëvolueerd bij TomTom en verloopt nu al lang zonder grote problemen. Het werkt, maar het is behoorlijk wat overhead om te onderhouden. Als je de mogelijkheid hebt, raden we je aan om volledig naar Git te migreren.
Als je een andere benadering volgt om een tweerichtingssynchronisatie te handhaven, ben ik daar in ieder geval heel benieuwd naar. Vertel er wat over in de reacties hieronder. Of stuur een tweet naar @durdn of @atlassiandev.
Nogmaals bedankt aan Andrea Carlevato, Adolfo Bulfoni en Krzysztof Karczewski.
Deel dit artikel
Volgend onderwerp
Aanbevolen artikelen
Bookmark deze resources voor meer informatie over soorten DevOps-teams of voor voortdurende updates over DevOps bij Atlassian.