Git-Tutorial: Synchronisation (Teil 4: git push)

In dieser Tutorial-Reihe beschäftigen wir uns mit der Zusammenarbeit zwischen Software-Entwicklern in einem Git-basierten Projekt: Zunächst sollen Repositories synchronisiert werden. In den ersten Beiträgen ging es in diesem Zusammenhang darum, mit git remote Verbindungen zwischen Repos einzurichten, mit git fetch Commits zu importieren und mit git pull Upstream-Änderungen in ein lokales Repository zu mergen.

Mit git push können Commits nun von einem lokalen Repository in ein Remote-Repo transferiert werden. Dieser Befehl ist das Gegenstück zu git fetch. Während beim Fetching Commits in lokale Branches importiert werden, exportiert git push Commits in Remote-Branches. Es besteht die Möglichkeit, Änderungen zu überschreiben; entsprechend sorgfältig sollte der Befehl genutzt werden.

Nutzung

git push <remote> <branch>

Pusht den spezifizierten Branch zu <remote>, und zwar mit allen nötigen Commits und internen Objekten. Im Ziel-Repository wird ein lokaler Branch erstellt. Als Schutz vor dem Überschreiben von Commits unterbindet Git das Pushen, wenn es in einen Nicht-Fast-Forward-Merge im Ziel-Repository resultiert.

git push <remote> --force

Erzwingt das Pushen auch dann, wenn es in einem Nicht-Fast-Forward-Merge resultiert.

git push <remote> --all

Pusht alle lokalen Branches in den spezifizierten Remote-Branch.

git push <remote> --tags

Tags werden nicht automatisch gepusht, wenn man einen Branch pusht oder die Option --all nutzt. Die Option --tags sendet alle lokalen Tags zum Remote-Repository.

Anmerkungen

Der gebräuchlichste Anwendungsfall für git push ist das Veröffentlichen lokaler Änderungen in ein zentrales Repository. Hat ein Entwickler diverse lokale Commits akkumuliert und ist bereit, sie mit dem Rest des Teams zu teilen, räumt er sie (optional) mit einem interaktiven Rebase auf und pusht sie dann ins zentrale Repo.

Das Diagramm unten zeigt, was passiert, wenn der lokale master weiter fortgeschritten ist als der master im zentralen Repo und Änderungen mit git push origin master veröffentlicht werden. git push ist im Grunde das Gleiche wie die Ausführung von git merge master im lokalen Repository.

Vor dem Pushen:
git push 1

Nach dem Pushen:
git push 2

Pushen erzwingen

Git verhindert, dass die History des zentralen Repos überschrieben wird, in dem Push-Requests abgelehnt werden, wenn sie in Nicht-Fast-Forward-Merges resultieren. Ist die Remote-History also von der lokalen History divergiert, muss der Remote-Branch gepullt und in den lokalen Branch gemergt werden. Dann kann das Pushen erneut versucht werden. Das ähnelt dem Prozess von SVN zur Synchronisation mit dem zentralen Repo via svn update, ehe ein Changeset committet wird.

Die Option --force unterbindet dieses Verhalten und gleicht den Branch im Remote-Repository dem lokalen Branch an. Dabei werden alle Upstream-Änderungen gelöscht, die seit dem letzten Pull des Entwicklers womöglich hinzugekommen sind. Der einzige sinnvolle Anwendungsfall für die Option --force ist der, wenn ein Entwickler merkt, dass seine gerade geteilten Commits fehlerhaft waren, und er diese mit git commit --amend oder einem interaktiven Rebase gefixt hat. Allerdings muss er dann absolut sicher sein, dass in der Zwischenzeit kein anderes Teammitglied diese Commits gepullt hat.

Nur in leere Repos pushen

Zusätzlich ist es empfehlenswert, nur in Repositories zu pushen, die mit der Option --bare erstellt wurden. Da Pushen die Struktur des Remote-Branchs durcheinanderbringt, ist es wichtig, nie in Repositories anderer Entwickler zu pushen. Da leere Repos jedoch kein Arbeitsverzeichnis haben, kann die Arbeit anderer Teammitglieder auch nicht gefährdet werden.

Beispiel

Das folgende Beispiel zeigt eine der Standardmethoden zur Veröffentlichung lokaler Änderungen in ein zentrales Repository auf:

git checkout master
git fetch origin master
git rebase -i origin/master
# Squash commits, fix up commit messages etc.
git push origin master

Da bereits sichergestellt ist, dass der lokale master-Branch aktuell ist, resultiert hieraus ein Fast-Forward-Merge. Git gibt keine Hinweise in Bezug auf Nicht-Fast-Forward-Merges aus, wie sie oben diskutiert wurden.

In der in Kürze folgenden nächsten Tutorial-Reihe widmen wir uns Pull-Requests.

Git und Stash effektiv und produktiv nutzen? Wir sind Ihr Partner!

Kennen Sie Stash, Atlassians Git-Repository-Managementsystem? Stash bietet eine zentrale Lösung zum Management des gesamten distributierten Codes: Hier kommen alle Git-Repositories im Unternehmen zusammen, hier finden Entwickler immer die letzte offizielle Version eines Projekts, hier können Projektverantwortliche Berechtigungen kontrollieren, um sicherzustellen, dass die richtigen Nutzer Zugriff auf den richtigen Code haben. Möchten Sie mehr erfahren? Wir sind offizieller Vertriebspartner von Atlassian und einer der größten Atlassian Experts Partner weltweit. Gerne unterstützen wir Sie bei der Evaluierung, Lizenzierung und Adaption von Stash.

Übrigens: //SEIBERT/MEDIA bietet auch professionelle Grundlagen- und Aufbau-Workshops zu Git und Atlassian Stash an.

Weiterführende Infos

99 Argumente für Stash als Git-Repository-Manager
Branch-basierte Git-Workflows mit Stash adaptieren
Echte Integration: Das Zusammenspiel von JIRA, Stash und Bamboo
Interview: Die Vorteile von Git in der Software-Entwicklung und die Möglichkeiten von Stash
So funktioniert die Lizenzierung von Atlassian-Produkten