Close

Git Merge-Konflikte

Versionskontrollsysteme werden verwendet, um Beiträge von mehreren verteilten Autoren (in der Regel Entwickler) zu verwalten. Manchmal kann es vorkommen, dass mehrere Entwickler versuchen, denselben Inhalt zu bearbeiten. Wenn Entwickler A Code bearbeiten möchte, an dem Entwickler B gerade arbeitet, kann es zu einem Konflikt kommen. Um das Auftreten von Konflikten zu vermeiden, arbeiten Entwickler in voneinander getrennten isolierten Branches. Mit dem Befehl git merge werden in erster Linie separate Branches kombiniert und eventuell bestehende Bearbeitungskonflikte behoben.


Grundlegendes zu Merge-Konflikten


Konflikte entstehen in der Regel dann, wenn zwei Personen dieselben Zeilen in einer Datei geändert haben oder ein Entwickler eine Datei löscht, während ein anderer Entwickler diese ändert. In diesen Fällen kann Git nicht automatisch entscheiden, welcher Vorgang richtig ist. Die Konflikte betreffen nur den Entwickler, der den Merge durchführt – der Rest des Teams bemerkt von dem Konflikt nichts. Git kennzeichnet die betreffende Datei als "in Konflikt stehend" und stoppt den Merge-Vorgang. Es ist dann Aufgabe des Entwicklers, den Konflikt zu lösen.

Arten von Merge-Konflikten


Bei einem Merge können an zwei separaten Stellen Konflikte entstehen: zu Beginn und während des Merge-Vorgangs. Im Folgenden sprechen wir darüber, wie jedes dieser Konfliktszenarien behandelt werden kann.

Git kann Merge nicht starten

Der Start eines Merge-Vorgangs schlägt fehl, wenn Git erkennt, dass Änderungen entweder im Arbeitsverzeichnis oder im Staging-Bereich des aktuellen Projekts vorgenommen wurden. Git führt den Merge nicht aus, weil diese ausstehenden Änderungen durch die Commits überschrieben werden könnten, die gemergt werden. Wenn dies geschieht, liegt das nicht an Konflikten mit anderen Entwicklern, sondern an Konflikten mit ausstehenden lokalen Änderungen. Der lokale Status muss mithilfe der Befehle git stash, git checkout, git commit oder git reset stabilisiert werden. Ein Merge-Fehler beim Start gibt die folgende Fehlermeldung aus:

error: Entry '<fileName>' not uptodate. Cannot merge. (Changes in working directory)

Bei Git tritt während dem Merge-Vorgang ein Fehler auf

Ein Fehler WÄHREND eines Merge-Vorgangs weist auf einen Konflikt zwischen dem aktuellen lokalen Branch und dem Branch hin, der gerade gemergt wird. Dies wiederum bedeutet einen Konflikt mit dem Code eines anderen Entwicklers. Git wird alles versuchen, um die Dateien zu mergen, überlässt dir aber die Aufgabe, Probleme mit in Konflikt stehenden Dateien manuell zu beheben. Bei einem Fehler während des Merge-Vorgangs wird die folgende Fehlermeldung ausgegeben:

Konsolenfenster
Zugehöriges Material

Git-Protokoll für Fortgeschrittene

Bitbucket-Logo
Lösung anzeigen

Git kennenlernen mit Bitbucket Cloud

error: Entry '<fileName>' would be overwritten by merge. Cannot merge. (Changes in staging area)

Erstellen eines Merge-Konflikts


Damit du mit Merge-Konflikten vertrauter wirst, wird im nächsten Abschnitt ein Konflikt simuliert, der später untersucht und gelöst werden soll. Für das Beispiel wird eine Unix-ähnliche Git-CLI (Command Line Interface) verwendet, über die diese Simulation ausgeführt wird.

$ mkdir git-merge-test
$ cd git-merge-test
$ git init .
$ echo "this is some content to mess with" > merge.txt
$ git add merge.txt
$ git commit -am"we are commiting the inital content"
[main (root-commit) d48e74c] we are commiting the inital content
1 file changed, 1 insertion(+)
create mode 100644 merge.txt

Dieses Codebeispiel führt eine Reihe von Befehlen aus, mit denen Folgendes erreicht wird:

  • Erstelle ein neues Verzeichnis namens git-merge-test, wechsle zu diesem Verzeichnis und initialisiere es als neues Git-Repository.
  • Erstelle eine neue Textdatei merge.txt mit einigen Inhalten.
  • Füge merge.txt zum Repository hinzu und committe die Datei.

Jetzt ist ein neues Repository mit einem main-Branch und einer Datei namens merge.txt mit Inhalten entstanden. Als Nächstes erstellen wir einen neuen Branch, der für einen in Konflikt stehenden Merge-Vorgang verwendet werden soll.

$ git checkout -b new_branch_to_merge_later
$ echo "totally different content to merge later" > merge.txt
$ git commit -am"edited the content of merge.txt to cause a conflict"
[new_branch_to_merge_later 6282319] edited the content of merge.txt to cause a conflict
1 file changed, 1 insertion(+), 1 deletion(-)

Die nachstehende Befehlsreihenfolge bewirkt Folgendes:

  • Du erstellst einen neuen Branch namens new_branch_to_merge_later und checkst ihn aus.
  • Du überschreibst den Inhalt in merge.txt.
  • Du committest den neuen Inhalt.

Mit diesem neuen Branch new_branch_to_merge_later haben wir einen Commit erstellt, der die Inhalte von merge.txt überschreibt.

git checkout main
Switched to branch 'main'
echo "content to append" >> merge.txt
git commit -am"appended content to merge.txt"
[main 24fbe3c] appended content to merge.tx
1 file changed, 1 insertion(+)

Mithilfe dieser Befehlskette wird der main-Branch ausgecheckt, der Datei merge.txt Inhalt hinzugefügt und dieser dann committet. Mit diesem Schritt werden aus unserem Beispiel-Repository zwei neue Commits: einer im main-Branch und einer im Branch namens new_branch_to_merge_later. An dieser Stelle lassen wir Git new_branch_to_merge_later mergen und beobachten, was passiert.

$ git merge new_branch_to_merge_later
Auto-merging merge.txt
CONFLICT (content): Merge conflict in merge.txt
Automatic merge failed; fix conflicts and then commit the result.

BUMM 💥. Es ist ein Konflikt aufgetreten. Danke für den Hinweis, Git!

Identifizierung von Merge-Konflikten


Wie wir aus dem vorangehenden Beispiel gelernt haben, erstellt Git einen beschreibenden Text, der uns über das Auftreten eines KONFLIKTS informiert. Detailliertere Informationen dazu erhalten wir durch die Ausführung des Befehls git status.

$ git status
On branch main
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)

Unmerged paths:
(use "git add <file>..." to mark resolution)

both modified:   merge.txt

Die Ausgabe von git status weist darauf hin, dass der Konflikt zu nicht gemergten Pfaden geführt hat. Die Datei merge.text wird jetzt im Status "modifiziert" angezeigt. Sehen wir uns die Datei an, um herauszufinden, was geändert wurde.

$ cat merge.txt
<<<<<<< HEAD
this is some content to mess with
content to append
=======
totally different content to merge later
>>>>>>> new_branch_to_merge_later

Hier haben wir den Befehl cat verwendet, um die Inhalte der Datei merge.txt hervorzuheben, und können feststellen, dass seltsame neue Ergänzungen gemacht wurden:

  • <<<<<<< HEAD
  • =======
  • >>>>>>> new_branch_to_merge_later

Betrachte diese neuen Zeilen als "Konflikt-Trennlinien". Die Zeile ======= ist das "Zentrum" des Konflikts. Alle Inhalte zwischen der Mitte und der Zeile <<<<<<< HEAD sind Inhalte, die im aktuellen Haupt-Branch vorhanden sind, auf den die HEAD-Referenz verweist. Hingegen ist alles, was zwischen der Mitte und >>>>>>> new_branch_to_merge_later liegt, Inhalt, der in unserem zu mergenden Branch vorliegt.

Behebung von Merge-Konflikten mithilfe der Befehlszeile


Der direkteste Weg, um Merge-Konflikte zu beheben, ist die Bearbeitung der in Konflikt stehenden Datei. Öffne hierzu die Datei merge.txt im Editor deiner Wahl. Bei unserem Beispiel hier entfernen wir einfach alle problematischen Trennlinien. Der geänderte Inhalt in merge.txt sollte wie folgt aussehen:

this is some content to mess with
content to append
totally different content to merge later

Sobald du die Datei bearbeitet hast, kannst du mit git add merge.txt den neu gemergten Inhalt stagen. Zum Abschluss des Merge-Vorgangs erstellst du einen neuen Commit, indem du folgenden Befehl ausführst:

git commit -m "merged and resolved the conflict in merge.txt"

Git erkennt, dass der Konflikt behoben wurde, und erstellt einen neuen Merge-Commit, um den Vorgang abzuschließen.

Git-Befehle für die Behebung von Merge-Konflikten


Allgemeine Tools

git status

Der status-Befehl wird für die Arbeit mit Git häufig verwendet und während eines Merge-Vorgangs können damit in Konflikt stehende Dateien identifiziert werden.

git log --merge

Durch die Übergabe des Arguments --merge an den git log-Befehl wird ein Protokoll mit einer Liste an Commits erstellt, die zwischen mergenden Branches für Konflikte sorgen.

git diff

Mithilfe von diff lassen sich Unterschiede zwischen Status von Repositorys/Dateien einfacher auffinden, was für die Prognose und Vermeidung von Merge-Konflikten nützlich ist.

Tools für den Fall, wenn Git keinen Merge-Vorgang starten kann

git checkout

Der Befehl checkout kann verwendet werden, um Änderungen in Dateien rückgängig zu machen oder um Branches zu wechseln.

git reset --mixed

reset wird genutzt, um Änderungen am Arbeitsverzeichnis und am Staging-Bereich zu widerrufen.

Tools für den Fall, wenn während eines Merge-Vorgangs Git-Konflikte entstehen

git merge --abort

Durch die Ausführung des Befehls git merge mit der Option --abort kannst du den Merge-Prozess verlassen und den Branch auf den Status vor dem Merge zurücksetzen.

git reset

Git reset kann während eines Merge-Konflikts verwendet werden, um in Konflikt stehende Dateien auf einen als funktionierend bekannten Status zurückzusetzen.

Zusammenfassung


Merge-Konflikte können eine ziemliche Wirkung haben. Zum Glück bietet Git leistungsstarke Tools, um Konflikten aus dem Weg zu gehen oder sie zu lösen. Git kann die meisten Merge-Vorgänge dank automatischer Merging-Features selbst handhaben. Ein Konflikt entsteht, wenn in zwei separaten Branches Bearbeitungen derselben Zeile in einer Datei vorgenommen wurden oder wenn eine Datei in einem Branch gelöscht, aber in einem anderen bearbeitet wurde. Konflikte entstehen am häufigsten bei der Arbeit in einer Teamumgebung.

Es gibt zahlreiche Tools, um Merge-Konflikte zu lösen. Git verfügt über genügend Befehlszeilentools, die hier besprochen wurden. Weitere detaillierte Informationen zu diesen Tools findest du auf den jeweiligen Seiten zu git log, git reset, git status, git checkout und git reset. Neben Git bieten viele Tools von Drittanbietern optimierte Supportfunktionen für Merge-Konflikte an.


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