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 p4
Wenn 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.py
Bearbeite die Datei ~/.gitconfig
, indem du Folgendes hinzufügst:
[alias]
p4 = !~/bin/bit-p4.py
Führe dann git p4
erneut aus. Dir sollten keine Fehler angezeigt werden. Das Tool ist installiert.
Zugehöriges Material
Verschieben eines vollständigen Git-Repositorys
Lösung anzeigen
Git kennenlernen mit Bitbucket Cloud
Ü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 sync
Der 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/main
nutzen:
git checkout -b p4-integ origin/p4/main
Anschließ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 sync
Die 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)
Referenzen
für denp4
-Remote-Branch (optional):
git symbolic-ref -d refs/remotes/p4/HEAD
git update-ref -d refs/remotes/p4/main
- Erstelle künstliche (auch bekannt als gefälschte) Remote-Referenzen, die auf den letzten Commit auf
p4-integ
inorigin
verweisen:
git update-ref refs/remotes/p4/main remotes/origin/p4-integ
git symbolic-ref refs/remotes/p4/HEAD refs/remotes/p4/main
Der 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/main
Die 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 rebase
Danach 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 develop
- Achte darauf, dass du die neuesten Tags lokal verfügbar hast:
git fetch --tags
- Verwende eine temporäre
Bereinigung
für den Fall, dass du Commits entfernen musst, die sich bereits inP4
befinden (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-integ
- Mit einem interaktiven Rebase kann dies stattdessen so erledigt werden:
git rebase -i tag/last-p4-integ
- Verwende
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
-Branchesmain
unddevelop
als 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..cleanup
- Sende an
P4
und synchronisierep4-integ
:
git p4 submit
git p4 sync --branch=refs/remotes/p4/main
git reset --hard refs/remotes/p4/main
- Lösche den temporären Rebase-Branch:
git branch -D cleanup
- Entferne 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-integ
- Aktualisiere das Tag
last-p4-integ
so, dass es auf den neuen Integrationspunkt inP4
zeigt:
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
Fü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 rebase
- Folgendes 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 p4mergebranch
- Wenn 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-integ
- Erstelle 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-integ
undtag/last-p4-integ
auforigin
:
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.
Diesen Artikel teilen
Nächstes Thema
Lesenswert
Füge diese Ressourcen deinen Lesezeichen hinzu, um mehr über DevOps-Teams und fortlaufende Updates zu DevOps bei Atlassian zu erfahren.