Letzte Änderung am 26. April 2022 by Christoph Jüngling
Nehmen wir mal an, ein Entwickler-Kollege arbeitet mit mir an einem Projekt. Nun wollen wir uns über unsere lokalen Änderungen austauschen, ohne den Weg über einen gemeinsamen Server zu gehen. Wie geht das, was macht man dabei, und welche Möglichkeiten ergeben sich? Ein fiktives Szenario, das aber durchaus real sein könnte.
Mein Kollege hat für seine Arbeit eine eigene Quelle “origin” (egal ob Server oder Netzwerk-Verzeichnis) aufgesetzt, zu der er zwischendurch pusht. Es handelt sich wohl um ein Netzwerkverzeichnis, aber so genau weiß ich das nicht. Muss ich auch nicht.
Unter “juengling” verwaltet er mein Server-Repository, von dem er lesen, aber zu dem er nicht pushen kann. Sein aktueller Arbeits-Branch heißt “master”. Die Referenz auf sein eigenes Repository auf dem Fileserver nennt er “origin”. Auf meinen Stand “juengling/master” aufbauend hat er weiter gearbeitet. Drei Commits (er war dabei nicht sehr kreativ, was die Commit-Messages betrifft) hat er bereits auf sein eigenes Repository gepusht, zwei weitere noch nicht. Das spielt aber für dieses Szenario keine Rolle, denn über die Server arbeiten wir ja nicht.
So sieht das Git-Log bei ihm aus:
Nun möchte er mir seinen master-Branch mit seinen Änderungen zur Verfügung stellen, bevor dieser für alle Zeiten unveränderbar auf dem Server landet. So ein Szenario kann verschiedene Ursachen haben:
- mangelnde Verfügbarkeit des Servers/Internets
- ich will einfach nicht, dass andere meinen Code durcheinanderbringen :-)
- beabsichtigtes Code-Review vor der Übernahme in den produktiven Zweig
Der Kollege geht sinnvollerweise davon aus, dass der öffentlich verfügbare Stand (bei ihm wie gesagt „juengling/master“ genannt) auch mir bekannt ist. Dies ist also unsere gemeinsame Basis, ältere Commits müssen nicht übertragen werden.
Diese Vorgehensweise reduziert die Größe des Bundles auf das absolut notwendige. Bei fünf Commits spielt das noch keine so große Rolle, er könnte genausogut auch das komplette Repository bündeln. Aber manche Projekte sind ja auch etwas größer …
Leider gibt es in TortoiseGit keine Möglichkeit, ein Bundle über die graphische Oberfläche zu erstellen. Dies muss also über die Kommandozeile erledigt werden. Am einfachsten bezieht mein Kollege sich auf die vorhandenen Referenzen der beiden angesprochenen Softwarestände: “juengling/master” und den eigenen “master”:
git bundle create mein-stand.bundle juengling/master..master
Er bündelt also alle Commits, die auf der Grundlage des Branches „juengling/master“ basieren bis hoch zum aktuellen Stand des lokalen Branches „master“ in eine Datei namens „mein-stand.bundle“. Diese Datei schickt er mir per eMail zu. Das Bundle enthält nun auch den Hash-Wert des Commits, auf den es sich bezieht. So kann Git überprüfen, ob das Bundle überhaupt in das andere Repository gepullt werden kann.
Der Vorteil des obigen Befehls ist, dass auch nach einem “pull” vom Server dessen Bedeutung erhalten bleibt. Der “pull” setzt einfach die Referenz “juengling/master” auf einen anderen Commit, so dass ein danach erfolgender “git bundle create”-Befehl wiederum genau den Bereich zwischen “juengling/master” und “master” bündeln wird. Auch “master” mag inzwischen weiter gewandert sein. Es bietet sich also an, diesen Befehl in eine .cmd-Datei zu schreiben, die dann auch wieder per Maus-Doppelklick ausgeführt werden kann. So wird auch die Bundle-Datei immer gleich heißen, was die Aktion auf Empfängerseite ebenfalls erleichtert.
Der Empfänger
Ich verwende in meinem Repository die Quelle „origin“ wie es üblich ist. Diese zeigt bei mir auf meinen Server, was dem, was mein Kollege unter „juengling“ eingetragen hat, entspricht. Das ist kein Widerspruch, denn diese Branchnamen sind nur lokale Referenzen und damit beliebig austauschbar; man muss nur im jeweiligen Repository wissen, was sich dahinter verbirgt.
Als Empfänger des Bundles füge ich beim ersten Mal eine neue Remote-Quelle hinzu. Wenn das Bundle in Zukunft immer genauso heißt und an der gleichen Stelle liegt, brauche ich daran später nichts mehr zu verändern. Das wird automatisch der Fall sein, wenn mein Kollege den Tipp mit dem .cmd-File umgesetzt hat.
git remote add bundle C:\pfad\zu\mein-stand.bundle
Dies kann ich auch in TortoiseGit mit Rechtsklick / TortoiseGit / Settings / Git / Remote oder auf der Konsole tun. Wie die Remote-Referenz heißt, ist dabei wiederum egal, ich nenne sie hier einfach “bundle”. Wenn mehrere Kollegen das so machen, wäre der Name des Kollegen sicher sinnvoller. Natürlich muss dann auch das Bundle jeweils anders genannt werden.
Jetzt kann ich von dieser Quelle ganz normal in meinen master-Branch “pullen”:
git pull bundle master
Oder ich mache erstmal ein git remote update
bzw. in TortoiseGit Rechtsklick / Sync / Remote Update. Dann zeige ich mit aktiviertem All Branches im Log die Commits an und merge sie ggf. in meinen “master”.
Durch den “pull” (spätestens nach dem Sync und Merge) ist mein “master” dann auf dem Stand meines Kollegen, ich kann also direkt mit meinen Tests beginnen.
So oder so, das Ergebnis sieht bei mir nun so aus:
Neueste Kommentare