Close

Git merge

In Git kannst du einen geforkten Verlauf per Merging wieder zusammensetzen. Mit dem Befehl git merge kannst du die unabhängigen Entwicklungszweige, die mit git branch erstellt wurden, in einen einzigen Branch integrieren.

Beachte, dass alle folgenden Befehle in den aktuellen Branch gemergt werden. Der aktuelle Branch wird aktualisiert, um den Projektstand des Merges wiederzugeben, doch der Ziel-Branch bleibt davon komplett unberührt. Zur Erinnerung: Der Befehl git merge wird also oft im Zusammenhang mit git checkout zum Auswählen des aktuellen Branches und git branch -d zum Löschen des veralteten Ziel-Branches genutzt.


Wie funktioniert "git revert"?


Mit git merge werden mehrere Commit-Abfolgen in einen einheitlichen Verlauf zusammengeführt. Vor allem wird git merge genutzt, um zwei Branches zu vereinen. Auf dieses Branch-Merging-Muster konzentrieren sich die folgenden Beispiele. In diesen Fällen sucht git merge zwischen zwei Commit-Pointern, was für gewöhnlich die Branch-Spitzen sind, einen gemeinsamen Basis-Commit. Sobald Git den gemeinsamen Basis-Commit gefunden hat, wird ein neuer "Merge-Commit" erstellt, um die Änderungen jeder Abfolge von Merge-Commits in der Warteschlange zusammenzuführen.

Nehmen wir an, wir haben ein neues Branch-Feature, das auf Basis des main-Branches erstellt wurde. Wir wollen diesen Feature-Branch nun in den main-Branch mergen.

Mergen des Feature-Branch in den Main-Branch
Konsolenfenster
Zugehöriges Material

Git-Protokoll für Fortgeschrittene

Bitbucket-Logo
Lösung anzeigen

Git kennenlernen mit Bitbucket Cloud

Mit diesem Befehl wird das angegebene Branch-Feature in den aktuellen Branch, den sogenannten main-Branch, gemergt. Git bestimmt den Merging-Algorithmus automatisch (später mehr dazu).

Neuer Merge-Commit-Knoten

Merge-Commits haben zwei übergeordnete Commits und unterscheiden sich damit von anderen Commits. Git versucht beim Erstellen eines Merge-Commits ganz automatisch, die separaten Verläufe zu mergen. Daten, die in beiden Verläufen geändert wurden, können von Git nicht automatisch zusammengeführt werden. Dieses Szenario führt in Git zu einem Versionskontrollkonflikt und erfordert den Eingriff des Benutzers.

Vorbereitung auf das Mergen


Damit das Mergen problemlos funktioniert, solltest du vorbereitend einige Schritte durchführen.

Den Merge-Ziel-Branch bestätigen


Führe git status aus, um sicherzustellen, dass der HEAD auch auf den Branch verweist, der wirklich das Ziel des Merge-Prozesses ist. Falls erforderlich, kannst du mit git checkout zu dem Branch wechseln, der das Merge-Ziel sein soll. In diesem Fall führen wir git checkout main aus.

Neueste Remote-Commits abrufen


Stelle sicher, dass der Merge-Ziel-Branch und der Merging-Branch mit den neuesten Remote-Änderungen aktualisiert wurden. Mit git fetch kannst du die neuesten Remote-Commits pullen. Vergewissere dich nach dem Abrufen der Commits, dass der main-Branch über die neuesten Updates verfügt, indem du git pull ausführst.

Verschmelzung


Wenn die zuvor beschriebenen Schritte zur Vorbereitung auf das Mergen abgeschlossen sind, kann der Merge-Vorgang beginnen. Führe dazu git merge aus, wobei der Name des Branches ist, der in den Merge-Ziel-Branch gemergt wird.

Fast-Forward-Merge


Ein Fast-Forward-Merge findet statt, wenn ein linearer Pfad von der Spitze des aktuellen Branches zum Ziel-Branch existiert. Statt die Branches tatsächlich zusammenzuführen, muss Git zur Integration der verschiedenen Verläufe lediglich die Spitze des aktuellen Branches an die Spitze des Ziel-Branches verschieben ("fast-forward"). Dadurch werden die Verläufe miteinander kombiniert, und alle Commits aus dem Ziel-Branch sind auch über den aktuellen Branch zugänglich. Ein Fast-Forward-Merge eines Features in den main-Branch könnte etwa so aussehen:

Feature-Knoten vor dem Main-Knoten, nach dem Fast-Forward sind beide auf demselben Knoten

Ein Fast-Forward-Merge ist jedoch nicht möglich, wenn die Branches voneinander abweichen. Wenn kein linearer Pfad zum Ziel-Branch existiert, kann Git die Branches nur mithilfe eines 3-Way-Merges zusammenführen. Für 3-Way-Merges gibt es einen speziellen Commit, um die beiden Verläufe miteinander zu verknüpfen. Die Benennung geht darauf zurück, dass Git drei Commits zum Durchführen des Merge-Commits verwendet: für die beiden Branch-Spitzen und ihren gemeinsamen Vorgänger.

Diagramm nach 3-Way-Merge

Beide Merge-Strategien stehen dir offen. Viele Entwickler bevorzugen jedoch Fast-Forward-Merges (mit Unterstützung von Rebasing) für kleine Features oder Bugfixes und greifen nur zur Integration langlebigerer Features auf 3-Way-Merges zurück. Bei der letzten Strategie dient der entstehende Merge-Commit zum symbolischen Zusammenführen der beiden Branches.

Unser erstes Beispiel zeigt einen Fast-Forward-Merge. Mit dem Code unten werden ein neuer Branch erstellt, zwei Commits zu diesem Branch hinzugefügt und der Branch dann mit einem Fast-Forward-Merge in den Hauptzweig integriert.

# Start a new feature
git checkout -b new-feature main
# Edit some files
git add <file>
git commit -m "Start a feature"
# Edit some files
git add <file>
git commit -m "Finish a feature"
# Merge in the new-feature branch
git checkout main
git merge new-feature
git branch -d new-feature

Dieser Workflow ist für kurzlebige Themen-Branches üblich, die weniger als Organisationstool für langlebigere Features als vielmehr zur isolierten Entwicklung genutzt werden.

Außerdem sollte Git bei git branch -d kein Problem melden, da der Zugriff auf das neue Feature (new-feature) nun vom Haupt-Branch aus möglich ist.

Falls du während eines Fast-Forward-Merges zu Dokumentationszwecken einen Merge-Commits durchführen musst, führe git merge mit der Option --no-ff aus.

git merge --no-ff <branch>

Mit diesem Befehl wird der angegebene Branch in den aktuellen Branch gemergt. Dabei wird immer ein Merge-Commit erzeugt (auch bei Fast-Forward-Merges). Das ist nützlich, wenn du alle Merges in deinem Repository dokumentieren willst.

3-Way-Merge


Das nächste Beispiel ist sehr ähnlich. Hier ist jedoch ein 3-Way-Merge erforderlich, weil der main-Branch fortgeführt und gleichzeitig das Feature bearbeitet wird. Dieses Szenario kommt häufig vor, wenn es um umfangreiche Features geht oder mehrere Entwickler zeitgleich an einem Projekt arbeiten.

Start a new feature
git checkout -b new-feature main
# Edit some files
git add <file>
git commit -m "Start a feature"
# Edit some files
git add <file>
git commit -m "Finish a feature"
# Develop the main branch
git checkout main
# Edit some files
git add <file>
git commit -m "Make some super-stable changes to main"
# Merge in the new-feature branch
git merge new-feature
git branch -d new-feature

Beachte, dass es für Git unmöglich ist, einen Fast-Forward-Merge durchzuführen, da der main-Branch ohne Zurückverfolgung nicht zu new-feature verschoben werden kann.

In den meisten Workflows wäre new-feature ein viel größeres Feature mit einer langen Entwicklungszeit. Daher würden neue Commits in der Zwischenzeit im main-Branch erscheinen. Wenn dein Feature-Branch aber denselben Umfang hat wie im Beispiel oben, würdest du ihn wahrscheinlich besser auf den main-Branch rebasen und einen Fast-Forward-Merge durchführen. So vermeidest du, dass unnötige Merge-Commits den Projektverlauf aufblähen.

Konflikte lösen


Wenn du versuchst, zwei Branches zu mergen, und es in beiden Branches Änderungen in demselben Teil derselben Datei gibt, dann weiß Git nicht, welche Version übernommen werden soll. In einer solchen Situation wird der Vorgang vor dem Merge-Commit angehalten und du kannst den Konflikt manuell lösen.

Das Tolle am Merging-Prozess in Git: Mit dem gewohnten Workflow zum Bearbeiten, Stagen und Durchführen von Commits kannst du auch Merge-Konflikte lösen. Führe bei einem Merge-Konflikt einfach den Befehl git status aus und die betroffenen Dateien werden angezeigt. Wenn zum Beispiel in beiden Branches derselbe Abschnitt von hello.py geändert wurde, wird dir in etwa Folgendes angezeigt:

On branch main
Unmerged paths:
(use "git add/rm ..." as appropriate to mark resolution)
both modified: hello.py

Darstellung von Konflikten


Wenn Git während eines Merge-Vorgangs einen Konflikt feststellt, werden in den betroffenen Dateien Anfang und Ende der Inhalte, die in Konflikt stehen, optisch gekennzeichnet. Die optische Kennzeichnung sieht wie folgt aus: <<<<<<<, =======, und >>>>>>>. Es ist hilfreich, während eines Merges nach dieser Kennzeichnung Ausschau zu halten, um mögliche Konflikte zu erkennen.

here is some content not affected by the conflict
<<<<<<< main
this is conflicted text from main
=======
this is conflicted text from feature branch
>>>>>>> feature branch;

Im Allgemeinen handelt es sich bei dem Inhalt vor der Kennzeichnung ======= um den Merge-Ziel-Branch, während der Teil danach der Merging-Branch ist.

Sobald du ausgemacht hast, welche Abschnitte in Konflikt stehen, kannst du den Merge nach deinen Vorstellungen korrigieren. Wenn du den Merge abgeschlossen hast, musst du lediglich den Befehl git add auf die in Konflikt stehende(n) Datei(en) ausführen, um Git zu sagen, dass sie gelöst sind. Anschließend führst du einen normalen git commit aus, um den Merge-Commit zu erzeugen. Der Prozess ist derselbe wie beim Committen eines gewöhnlichen Snapshots. Normale Entwickler können eigene Merges also ganz einfach verwalten.

Beachte, dass es nur bei 3-Way-Merges zu Merge-Konflikten kommt. In Fast-Forward-Merges können keine Änderungskonflikte entstehen.

Zusammenfassung


Dieses Dokument bietet einen Überblick über den Befehl git merge. Das Mergen ist bei der Arbeit mit Git ein wesentlicher Prozess. Wir haben die internen Mechanismen hinter dem Merging und die Unterschiede zwischen einem Fast-Forward-Merge und einem echten sogenannten 3-Way-Merge behandelt. Das sind einige der wichtigsten Punkte:

1. Durch das Mergen in Git werden mehrere Commit-Abfolgen in einen einheitlichen Commit-Verlauf zusammengeführt.

2. Es gibt allgemein gesehen zwei Merging-Möglichkeiten in Git: Fast-Forward- und 3-Way-Merging.

3. Git kann Commits automatisch mergen, vorausgesetzt, es gibt keine Änderungen, die zu Konflikten mit beiden Commit-Abfolgen führen.

In diesem Dokument werden andere Git-Befehle integriert und referenziert, wie: git branch, git pull und git fetch. Weitere Informationen findest du auf den entsprechenden eigenständigen Seiten.


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.

Mitarbeiter arbeiten mit unzähligen Tools zusammen

Bitbucket-Blog

Abbildung: DevOps

DevOps-Lernpfad

Demo Den: Feature-Demos mit Atlassian-Experten

So funktioniert Bitbucket Cloud mit Atlassian Open DevOps

Melde dich für unseren DevOps-Newsletter an

Thank you for signing up