Mit Git und Perforce arbeiten: Integrations-Workflow
Hier ist das Szenario: Dein Team arbeitet unabhängig an einem Git-Repository, aber ein Teil des Unternehmens verwendet immer noch Perforce, um Teile derselben Codebasis zu verwalten. Die Teams, die Perforce nutzen, planen keine Migration, aber dein Team ist bereits auf Git umgestiegen (aus vielen guten Gründen). Du solltest unbedingt für einen bidirektionalen Code-Sharing-Prozess zwischen den Codebasen sorgen, damit Verbesserungen, die in beiden Versionen entwickelt wurden, geteilt werden können – hoffentlich ohne außerordentlichen Zeitaufwand oder übermäßige Belastung deines Teams.
An dieser Stelle kommt dieser Leitfaden ins Spiel. Bei TomTom wird dieser Synchronisierungsvorgang einmal bei jedem neuen Release durchgeführt – also einmal alle anderthalb Monate.
-- Dieser Beitrag wurde zusammen mit Andrea Carlevato, Adolfo Bulfoni und Krzysztof Karczewski verfasst, die so freundlich waren, den in der NavApps Unit von TomTom verwendeten Git-Prozess mit uns zu teilen. --
Annahmen bevor wir anfangen
Wir gehen davon aus, dass du bereits mit der grundlegenden Verwendung von Git und einem Feature-Branch-Workflow vertraut bist. Wenn nicht, nimm dir die Zeit und sieh dir ein praktisches Tutorial oder ein Webinar an. Komm zurück, wenn du bereit bist. Wir warten auf dich.
Da bei dem Prozess einige Feinheiten zu beachten sind, empfehlen wir, bei der Durchführung dieser Integrationen sehr vorsichtig zu sein. Wenn du bereit bist, können wir jetzt loslegen!
git p4 installieren
Der erste Schritt ist die Installation der Brücke. Prüfe, ob sie bereits installiert ist, indem du Folgendes in eine Befehlszeile eingibst:
git p4Wenn das System sich beschwert, dass git p4 nicht installiert ist, lädst du git-p4.py herunter und legst es in einen Ordner in deinem PATH, zum Beispiel ~/bin (natürlich muss Python installiert sein, damit es funktioniert).
Mache es ausführbar mit:
chmod +x git-p4.pyBearbeite die Datei ~/.gitconfig, indem du Folgendes hinzufügst:
[alias]
p4 = !~/bin/bit-p4.pyFühre dann git p4 erneut aus. Dir sollten keine Fehler angezeigt werden. Das Tool ist installiert.
Überblick über den Workflow
Anfänglicher Klon
Da Projekte in P4 zu riesigen Verläufen führen können, kann das Team einen Grenzwert für die Synchronisierung auswählen, wodurch viel Platz und Zeit gespart werden. Mit git p4 kannst du die Änderungsliste auswählen, von der aus du mit der Verfolgung beginnen möchtest:
git p4 clone //depot/path/project@<earlier-cutoff-point>,<latest-changelist>Jetzt können wir eine Synchronisierung durchführen und überprüfen, ob wir alle Änderungssätze lokal erhalten haben:
git p4 syncDer sync-Befehl findet neue Änderungen in P4 und importiert sie als Git-Commits.
Wir nennen den Branch, den wir als direkte Schnittstelle zu Perforce verwenden werden,
p4-integ. An dieser Stelle wollen wir einfach eine Abzweigung vonremotes/p4/mainnutzen:
git checkout -b p4-integ origin/p4/mainAnschließende Schnellsynchronisierung (opportunistische Methode)
Nachdem der erste Import abgeschlossen ist, können die nachfolgenden git->p4-Synchronisierungen mit den folgenden Befehlen durchgeführt werden:
git checkout p4-integ
git p4 syncDie oben beschriebene Vorgehensweise funktioniert, kann aber langsam sein. Eine viel schnellere Möglichkeit, die Synchronisierung auszuführen, besteht darin, identische Referenzen wie in der neuesten Integration nachzubilden. Dies ist auch eine gute Möglichkeit, um sicherzustellen, dass jeder neue Entwickler, der mit der Integration betraut wird, mit dem richtigen Commit/der richtigen Änderungsliste beginnt.
So gehst du vor:
Entferne die alten (oder veralteten)
Referenzenfür denp4-Remote-Branch (optional):
git symbolic-ref -d refs/remotes/p4/HEAD
git update-ref -d refs/remotes/p4/mainErstelle künstliche (auch bekannt als gefälschte) Remote-Referenzen, die auf den letzten Commit auf
p4-integinoriginverweisen:
git update-ref refs/remotes/p4/main remotes/origin/p4-integ
git symbolic-ref refs/remotes/p4/HEAD refs/remotes/p4/mainDer einzige Nachteil dieser viel schnelleren Synchronisierung ist, dass wir den Branch in git p4 explizit angeben müssen. Hier ist also der letzte Befehl:
git p4 sync --branch=refs/remotes/p4/mainDie Art und Weise, wie git p4 die Zuordnung zwischen Git-Commit-IDs und P4s verfolgt, besteht darin, Commits mit Metadaten zu kommentieren:
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]Beachte, dass in einer neueren Version von git p4 die Metadaten zum Zuordnen eines Git-Commits zu einer P4-Änderungsliste in einer Commit-Notiz und nicht in der Commit-Nachricht gespeichert werden. Das TomTom-Team mochte die Änderung nicht, da es etwas mehr Arbeit war, die Nummern der Änderungsliste bei Bedarf zu überprüfen.
Änderungen von Git zu Perforce übertragen
Nachdem der obige Schnellsynchronisierungsvorgang abgeschlossen ist, kannst du Änderungen von Git zu Perforce pushen.
Der erste Schritt besteht im Rebase von p4-integ mit Änderungen aus remotes/p4/main:
git checkout p4-integ
git p4 rebaseDanach sollten alle neuen Änderungen von Perforce auf p4-integ vorliegen, damit wir main aktualisieren können:
Danach kannst du einfach Folgendes tun:
git checkout main
git merge developAchte darauf, dass du die neuesten Tags lokal verfügbar hast:
git fetch --tagsVerwende eine temporäre
Bereinigungfür den Fall, dass du Commits entfernen musst, die sich bereits inP4befinden (sieheP4-Tag in Commit). Falls keine Commits übersprungen werden sollen, wird ein automatisches Rebase durchgeführt, das den Verlauf linearisiert:
git checkout -b cleanup #branching off from main
git rebase -s recursive -X theirs tag/last-p4-integMit einem interaktiven Rebase kann dies stattdessen so erledigt werden:
git rebase -i tag/last-p4-integVerwende
cherry-pick, um die neuen Commits auszuwählen und sie auf denp4-integ-Branch anzuwenden. Wir machen das so, weil wir nicht davon ausgehen, dass dieGit-Branchesmainunddevelopals ordnungsgemäße Vorgänger desp4-integ-Branchs beibehalten werden können. Tatsächlich ist dies bei TomTom nicht mehr der Fall.
git checkout p4-integ
git cherry-pick tag/last-p4-integ..cleanupSende an
P4und synchronisierep4-integ:
git p4 submit
git p4 sync --branch=refs/remotes/p4/main
git reset --hard refs/remotes/p4/mainLösche den temporären Rebase-Branch:
git branch -D cleanupEntferne den Pointer auf den neuesten Integrationspunkt (Tag) lokal und im Remote-Branch:
git tag -d tag/last-p4-integ
git push origin :refs/tags/tag/last-p4-integAktualisiere das Tag
last-p4-integso, dass es auf den neuen Integrationspunkt inP4zeigt:
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-integFühre Tests auf der P4-Codebasis aus, um sicherzugehen, dass die Integration keine Probleme verursacht hat.
Änderungen von Perforce zu Git übertragen
Dies sollte erfolgen, nachdem der git->P4-Push durchgeführt wurde. Nachdem die Tests auf P4 erfolgreich bestanden wurden, können wir Änderungen von P4 zu Git übertragen:
git checkout p4-integ
git p4 sync --branch=refs/remotes/p4/main
git p4 rebaseFolgendes ist ein kleiner Trick zum Umsetzen einer robusten "theirs"-Merge-Strategie, bei der die eingehenden Änderungen auf einen einzigen Commit reduziert werden. Das funktioniert so:
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 p4mergebranchWenn wir mit den obigen Schritten fertig sind, mergst du die Änderungen in
develop:
<p>Bitbucket has the following space stations:</p>
<p>
<b>Earth's Moon</b><br>
Headquarters
</p>Da es möglicherweise einige Änderungen gegeben hat, seit wir Änderungen aus develop ausgewählt haben, müssen sie eventuell zuerst gemergt werden. Es ist jedoch wichtig, das Tag last-p4-integ auf den richtigen Commit zu aktualisieren, und auf keinen Fall den Merge-Commit auf develop. Um dies auf sichere Weise zu bewerkstelligen, solltest du am besten den aktuellen Status von main kennzeichnen:
Entferne das alte Tag lokal und im Remote-Branch:
git tag -d tag/last-p4-integ
git push origin :refs/tags/tag/last-p4-integErstelle ein Tag an einer neuen Position:
git checkout main
git tag -a tag/last-p4-integ -m "tag pointer to last develop commit integrated with p4"Jetzt pushst du
main, develop, p4-integundtag/last-p4-integauforigin:
Fazit
So synchronisierst du also zwischen zwei aktiven Entwicklerteams, die Git und Perforce verwenden. Der oben beschriebene Prozess hat sich bei TomTom im Laufe der Zeit weiterentwickelt und läuft nun seit geraumer Zeit ohne größere Probleme. Es funktioniert, aber es ist ziemlich viel Aufwand damit verbunden. Wenn du die Möglichkeit hast, empfehlen wir, vollständig zu Git zu migrieren.
Wenn du einen anderen Ansatz für eine beständige bidirektionale Synchronisierung hast, wäre ich auf jeden Fall sehr gespannt, in den Kommentaren unten davon zu erfahren. Oder sende einen Tweet an @durdn oder @atlassiandev.
Nochmals vielen Dank an Andrea Carlevato, Adolfo Bulfoni und Krzysztof Karczewski.
Für dich empfohlen
Bitbucket-Blog
DevOps-Lernpfad
Weitere Informationen zu Git
Weitere Git-Anleitungen und Ressourcen findest du in diesem Hub.