git merge
Auf dieser Seite finden Sie Informationen über den git merge Befehl, wie er funktioniert und den Unterschied zwischen Fast-Forward- und 3-Way-Merging.
Der Befehl git merge fügt zwei oder mehr Entwicklungslinien wieder zusammen. Wenn Sie ein Feature auf einem eigenen Branch abgeschlossen haben, nimmt git merge die Arbeit von diesem Branch und integriert sie in den Branch, auf dem Sie sich gerade befinden, und erzeugt dabei eine einzige kombinierte Historie.
Diese Seite erklärt, was während eines Merges passiert, den Unterschied zwischen einem Fast-Forward- und einem 3-Way-Merge, wie man einen Merge-Commit erzwingt und wie man einen Merge-Konflikt erkennt und auflöst.
Der Befehl arbeitet eng mit git branch (zum Erstellen und Löschen von Branches), git checkout (zum Wechseln des aufnehmenden Branches) und git pull (zum Aktualisieren vor dem Merge) zusammen. Wenn Sie eine lineare Historie ohne Merge-Commits bevorzugen, lesen Sie git rebase als Alternative.
So funktioniert es
Die primäre Verwendung von git merge besteht darin, zwei Branches zu kombinieren. Es wird auch verwendet, um mehrere Commits von einem Branch in einen anderen zu integrieren. In der folgenden Abbildung nimmt git merge zwei Branch-Spitzen und findet einen gemeinsamen Vorfahren-Commit zwischen ihnen. Der gemeinsame Basis-Commit wird verwendet, um einen neuen Merge-Commit zu erstellen, der die Änderungen beider Branches kombiniert. Hier haben wir zwei Branches: master und stage. Wir sollen den stage-Branch in den master-Branch mergen.

Merge-Commits sind einzigartig, da sie zwei übergeordnete Commits haben. Git kombiniert automatisch getrennte Historien beim Erstellen eines neuen Merge-Commits. Wenn jedoch beide Branches dieselben Zeilen ändern, kann Git sie nicht automatisch kombinieren, was zu einem Merge-Konflikt führt.

Merge-Prozess
Bevor Sie den Merge-Prozess starten, führen Sie folgende Schritte aus:
- Stellen Sie sicher, dass Sie sich auf dem richtigen aufnehmenden Branch befinden. Führen Sie
git checkout <receiving branch>aus, um dorthin zu wechseln. - Aktualisieren Sie den Zielbranch mit den neuesten Remote-Änderungen. Führen Sie
git pullaus, um die neuesten Remote-Commits zu holen und zu integrieren. - Der letzte Schritt ist die Ausführung von
git merge <branch name>, wodurch der Branch angegeben wird, der in den aufnehmenden Branch gemergt werden soll.
Fast-Forward-Merge
Ein Fast-Forward-Merge tritt auf, wenn der Pfad vom aktuellen Branch zum Zielbranch linear ist. Der Fast-Forward-Merge kombiniert die Historien, da alle Commits, die vom Zielbranch aus erreichbar sind, auch über den aktuellen Branch verfügbar sind. Hier ist ein Beispiel für einen Fast-Forward-Merge:

Wenn die beiden Historien divergieren, verwendet Git den 3-Way-Merge als Alternative. Der 3-Way-Merge verwendet einen dedizierten Commit, um zwei Historien zu kombinieren.

Fast-Forward-Merges werden typischerweise für kleine Features oder Bugfixes verwendet, während 3-Way-Merges zur Integration langfristiger Features eingesetzt werden. Die folgenden Beispiele verwenden einen Fast-Forward-Merge:
git merge
# Start the stage
git checkout -b stage master
# Edit some files
git add <file>
git commit -m "Start with the stage"
# Edit some files
git add <file>
git commit -m "Finish with the stage"
# Merge in the stage branch
git checkout master
git merge stage
git branch -d stageWir führen git branch -d aus, um den stage-Branch zu löschen, da stage jetzt vom master-Branch aus zugänglich ist.
Der git merge-Befehl mit der Option --no-ff wird ausgeführt, wenn Sie während eines Fast-Forward-Merges einen Merge-Commit benötigen, um den angegebenen Branch in den aktuellen Branch zu mergen, wobei immer ein Merge-Commit erzeugt wird (auch im Fall eines Fast-Forward-Merges):
git merge --no-ff
git merge --no-ff <branch>3-Way-Merge
Dieses Szenario erfordert einen 3-Way-Merge, wenn der master-Branch fortschreitet, während der stage-Branch noch in Entwicklung ist. Dies wird verwendet, wenn Teammitglieder gleichzeitig an einem großen Feature arbeiten:
the git merge command
# Start the stage
git checkout -b stage master
# Edit some files
git add <file>
git commit -m "Start with the stage"
# Edit some files
git add <file>
git commit -m "Finish with the stage"
# Develop the master branch
git checkout master
# Edit some files
git add <file>
git commit -m "Make some super-stable changes to master"
# Merge in the stage branch
git merge stage
git branch -d stageIm obigen Beispiel wäre stage ein größeres Feature, das viel Zeit zur Entwicklung benötigt, weshalb wir einen 3-Way-Merge verwenden. Wenn Ihr Feature klein ist, sollten Sie lieber einen Fast-Forward-Merge verwenden, um unnötige Commits zu vermeiden, die die Projekthistorie unübersichtlich machen.
Nützliche Merge-Optionen
Diese Flags ändern das Verhalten von git merge:
| Option | Beschreibung |
|---|---|
--no-ff | Erstellt immer einen Merge-Commit, auch wenn ein Fast-Forward möglich ist. Hält den Feature-Branch in der Historie sichtbar. |
--ff-only | Merged nur, wenn ein Fast-Forward möglich ist; andernfalls Abbruch. Nützlich in Skripten, um einen Merge-Commit abzulehnen. |
--squash | Kombiniert alle Commits des Branches in einen einzigen Satz von gestagten Änderungen (die Sie dann manuell committen). Kein Merge-Commit und kein zweites Elternteil. |
--abort | Stoppt einen konfliktbehafteten Merge und stellt den Branch in seinen Zustand vor dem Merge wieder her. |
-m "<msg>" | Legt die Merge-Commit-Nachricht direkt fest, anstatt einen Editor zu öffnen. |
Ein Squash-Merge ist praktisch, wenn ein Feature-Branch viele kleine „Work in Progress"-Commits enthält, die Sie nicht in der Haupthistorie haben möchten:
git merge --squash
git checkout master
git merge --squash stage
git commit -m "Add stage feature"Konfliktauflösung
Beim Mergen zweier Branches entstehen Merge-Konflikte, wenn derselbe Teil derselben Datei geändert wurde, da Git nicht automatisch bestimmen kann, welche Version verwendet werden soll. In diesem Fall hält Git vor der Erstellung des Merge-Commits an, damit Sie den Konflikt auflösen können. Der Git-Merge-Prozess verwendet einen Edit/Stage/Commit-Workflow zur Auflösung von Merge-Konflikten. Wenn ein Konflikt auftritt, zeigt git status die Dateien an, die aufgelöst werden müssen. Das folgende Bild erscheint, wenn die gleichen Teile der Datei example.txt geändert wurden:
git status
On branch master
Unmerged paths:
(use "git add/rm ..." as appropriate to mark resolution)
both modified: example.txtWenn Sie den Merge nicht fortsetzen möchten, können Sie ihn jederzeit durch Ausführen von git merge --abort abbrechen.
Wie Konflikte dargestellt werden
Im Falle von Konflikten bearbeitet Git den Inhalt der betroffenen Dateien mit visuellen Markierungen auf beiden Seiten des konflikthaften Inhalts. Konflikte können nur bei einem 3-Way-Merge auftreten — ein Fast-Forward-Merge führt nie zu Konflikten, da der aufnehmende Branch keine eigenen neuen Commits hatte, die in Konflikt geraten könnten.
Die primären Markierungen sind <<<<<<<, ======= und >>>>>>>. Sie helfen Ihnen, die konfliktbehafteten Abschnitte in Ihren Dateien zu finden.
git conflicts
here is some content not affected by the conflict
<<<<<<< master
this is conflicted text from master
=======
this is conflicted text from stage branch
>>>>>>> stageUm den Konflikt aufzulösen, öffnen Sie die Datei, löschen Sie die drei Markierungszeilen (<<<<<<<, =======, >>>>>>>), und bearbeiten Sie den verbleibenden Text zur gewünschten Version. Führen Sie dann git add <file> auf der konfliktbehafteten Datei aus, um sie als aufgelöst zu markieren, und führen Sie git commit aus, um den Merge-Commit zu erstellen.
Ein vollständiges Arbeitsbeispiel
Die folgende Sitzung erstellt zwei Branches, die dieselbe Zeile bearbeiten, merged sie, trifft auf einen Konflikt, löst ihn und schließt den Merge ab. Sie können diese Befehle in ein beliebiges leeres Verzeichnis einfügen, um es exakt zu reproduzieren.
reproduce a conflict and resolve it
git init demo && cd demo
echo "line one" > file.txt
git add file.txt
git commit -m "Initial commit"
# Create a branch and change the line there
git checkout -b stage
echo "change from stage" > file.txt
git commit -am "Edit on stage"
# Change the same line on master
git checkout master
echo "change from master" > file.txt
git commit -am "Edit on master"
# Merge stage into master -> conflict
git merge stage
# Auto-merging file.txt
# CONFLICT (content): Merge conflict in file.txt
# Automatic merge failed; fix conflicts and then commit the result.Nachdem Sie file.txt bearbeitet haben, um die gewünschte Version zu behalten, schließen Sie den Merge ab:
git add file.txt
git commit -m "Merge stage, keep resolved line"
git branch -d stageEinen Merge überprüfen
Bestätigen Sie das Ergebnis nach dem Merge mit git log. Die Flags --graph und --oneline zeichnen die Branch-Topologie, sodass ein Merge-Commit (mit zwei Elternteilen) leicht zu erkennen ist:
git log --oneline --graphWenn Sie entscheiden, dass ein abgeschlossener Merge ein Fehler war, kann git reset den Branch auf den Commit vor dem Merge zurücksetzen.