Close

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.

Databases
gerelateerd materiaal

Een volledige Git-repository verplaatsen

Logo Bitbucket
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 van remotes/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 remote p4 (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 in origin:
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 in P4 staan (zie P4-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 branch p4-integ te zetten. We doen het op deze manier omdat we er niet van uitgaan dat de git-branches main en develop bewaard kunnen worden als echte voorouders van de p4-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 synchroniseer p4-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 in P4 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 en tag/last-p4-integ naar origin:

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

Aanbevolen artikelen

Bookmark deze resources voor meer informatie over soorten DevOps-teams of voor voortdurende updates over DevOps bij Atlassian.

Mensen die samenwerken met een muur vol tools

Bitbucket-blog

Toelichting DevOps

DevOps-leertraject

Demo Den Feature-demo's met Atlassian-experts

Hoe Bitbucket Cloud werkt met Atlassian Open DevOps

Meld je aan voor onze DevOps-nieuwsbrief

Thank you for signing up