Frage Wie man Zusammenführungskonflikte in Git löst


Gibt es eine gute Möglichkeit zu erklären, wie Konflikte in Git gelöst werden können?


4123
2017-10-02 11:31


Ursprung


Antworten:


Versuchen: git mergetool

Es öffnet eine GUI, die Sie durch jeden Konflikt führt, und Sie wählen, wie Sie zusammenführen. Manchmal erfordert es nachher etwas Handarbeit, aber normalerweise genügt es. Es ist viel besser, als das Ganze mit der Hand zu machen.

Laut @JoshGlover Kommentar:

Der Befehl öffnet nicht notwendigerweise eine GUI, es sei denn, Sie installieren eine. Laufen git mergetool für mich resultierte vimdiff verwendet werden. Sie können eines der folgenden Tools installieren, um es stattdessen zu verwenden: meld, opendiff, kdiff3, tkdiff, xxdiff, tortoisemerge, gvimdiff, diffuse, ecmerge, p4merge, araxis, vimdiff, emerge.

Unten ist das zu verwendende Beispielverfahren vimdiff zum Lösen von Zusammenführungskonflikten. Beyogen auf dieser Link

Schritt 1: Führen Sie die folgenden Befehle in Ihrem Terminal aus

git config merge.tool vimdiff
git config merge.conflictstyle diff3
git config mergetool.prompt false

Dadurch wird vimdiff als Standard-Merge-Tool festgelegt.

Schritt 2: Führen Sie folgenden Befehl im Terminal aus

git mergetool

Schritt 3: Sie sehen eine vimdiff-Anzeige im folgenden Format

  +----------------------+
  |       |      |       |
  |LOCAL  |BASE  |REMOTE |
  |       |      |       |
  +----------------------+
  |      MERGED          |
  |                      |
  +----------------------+

Diese 4 Ansichten sind

LOCAL - das ist eine Datei aus dem aktuellen Zweig

BASE - gemeinsamer Vorfahr, wie Datei vor beiden Änderungen geschaut hat

REMOTE - Datei, die Sie in Ihre Filiale zusammenführen

MERGED - merge result, dies wird im Repo gespeichert

Sie können mit diesen Ansichten zwischen diesen Ansichten navigieren ctrl+w. Sie erreichen MERGED View direkt mit ctrl+w gefolgt von j.

Weitere Informationen über die Navigation mit vimdiff Hier und Hier

Schritt 4. Sie können die MERGED-Ansicht folgendermaßen bearbeiten

Wenn Sie Änderungen von REMOTE erhalten möchten

:diffg RE  

Wenn Sie Änderungen von BASE erhalten möchten

:diffg BA  

Wenn Sie Änderungen von LOCAL erhalten möchten

:diffg LO 

Schritt 5. Speichern, Beenden, Festschreiben und Aufräumen

:wqa Speichern und verlassen von vi

git commit -m "message"

git clean Entfernen Sie zusätzliche Dateien (z. B. * .orig), die mit dem Diff-Tool erstellt wurden.


2415
2017-10-02 17:50



Hier ist ein wahrscheinlicher Anwendungsfall von oben:

Sie werden einige Änderungen vornehmen, aber ups, Sie sind nicht auf dem neuesten Stand:

git fetch origin
git pull origin master

From ssh://gitosis@example.com:22/projectname
 * branch            master     -> FETCH_HEAD
Updating a030c3a..ee25213
error: Entry 'filename.c' not uptodate. Cannot merge.

Du wirst also auf dem Laufenden bleiben und es erneut versuchen, aber einen Konflikt haben:

git add filename.c
git commit -m "made some wild and crazy changes"
git pull origin master

From ssh://gitosis@example.com:22/projectname
 * branch            master     -> FETCH_HEAD
Auto-merging filename.c
CONFLICT (content): Merge conflict in filename.c
Automatic merge failed; fix conflicts and then commit the result.

Sie entscheiden sich also, sich die Änderungen anzusehen:

git mergetool

Oh, oh mein Gott, Upstream hat einige Dinge verändert, aber nur um meine Veränderungen zu nutzen ... nein ... ihre Veränderungen ...

git checkout --ours filename.c
git checkout --theirs filename.c
git add filename.c
git commit -m "using theirs"

Und dann versuchen wir ein letztes Mal

git pull origin master

From ssh://gitosis@example.com:22/projectname
 * branch            master     -> FETCH_HEAD
Already up-to-date.

Ta-da!


1607
2017-08-04 17:04



Ich finde, Merge-Tools helfen mir selten, den Konflikt oder die Auflösung zu verstehen. Ich bin normalerweise erfolgreicher, wenn ich die Konfliktmarker in einem Texteditor betrachte und git log als Ergänzung benutze.

Hier sind ein paar Tipps:

Tipp eins

Das Beste, was ich gefunden habe, ist die Verwendung des Mischkonflikts "diff3":

git config merge.conflictstyle diff3

Dies erzeugt Konfliktmarker wie folgt:

<<<<<<<
Changes made on the branch that is being merged into. In most cases,
this is the branch that I have currently checked out (i.e. HEAD).
|||||||
The common ancestor version.
=======
Changes made on the branch that is being merged in. This is often a 
feature/topic branch.
>>>>>>>

Der mittlere Abschnitt ist wie der gemeinsame Vorfahre aussah. Dies ist nützlich, da Sie es mit der oberen und unteren Version vergleichen können, um einen besseren Überblick darüber zu bekommen, was in den einzelnen Zweigen geändert wurde. Dadurch erhalten Sie eine bessere Vorstellung davon, was der Zweck jeder Änderung war.

Wenn der Konflikt nur wenige Zeilen umfasst, ist der Konflikt in der Regel sehr offensichtlich. (Zu wissen, wie man einen Konflikt behebt, ist sehr unterschiedlich; man muss sich bewusst sein, woran andere arbeiten. Wenn Sie verwirrt sind, ist es wahrscheinlich am besten, diese Person in Ihr Zimmer zu rufen, damit sie sehen können, was Sie suchen beim.)

Wenn der Konflikt länger ist, werde ich jeden der drei Abschnitte in drei separate Dateien schneiden und einfügen, wie "meins", "gemeinsam" und "ihres".

Dann kann ich die folgenden Befehle ausführen, um die zwei Diff-Hunks zu sehen, die den Konflikt verursacht haben:

diff common mine
diff common theirs

Dies ist nicht dasselbe wie die Verwendung eines Merge-Tools, da ein Merge-Tool auch alle nicht in Konflikt stehenden Diff-Hunks enthält. Ich finde das ablenkend.

Tipp zwei

Jemand hat das bereits erwähnt, aber das Verständnis der Absicht hinter jedem Diff-Buch ist im Allgemeinen sehr hilfreich, um zu verstehen, wo ein Konflikt herkommt und wie man damit umgeht.

git log --merge -p <name of file>

Dies zeigt alle Commits an, die diese Datei zwischen dem gemeinsamen Vorfahren und den beiden Köpfen, die du zusammenführst, berührt haben. (Es enthält also keine Commits, die bereits vor dem Zusammenführen in beiden Zweigen vorhanden sind.) Dies hilft Ihnen, Diff-Hunks zu ignorieren, die in Ihrem aktuellen Konflikt eindeutig keine Rolle spielen.

Tipp drei

Überprüfen Sie Ihre Änderungen mit automatisierten Tools.

Wenn Sie automatisierte Tests haben, führen Sie diese aus. Wenn Sie eine haben FusselLauf das. Wenn es sich um ein Build-fähiges Projekt handelt, dann erstellen Sie es vor dem Commit usw. In jedem Fall müssen Sie ein wenig testen, um sicherzustellen, dass Ihre Änderungen nichts kaputt gemacht haben. (Heck, sogar eine Zusammenführung ohne Konflikte kann Arbeitscode brechen.)

Tipp vier

Vorausplanen; mit Kollegen kommunizieren.

Vorausschauend und sich bewusst zu sein, woran andere arbeiten, kann dazu beitragen, Zusammenführungskonflikte zu vermeiden und / oder dazu beitragen, diese früher zu lösen - während die Details noch frisch sind.

Wenn Sie zum Beispiel wissen, dass Sie und eine andere Person an verschiedenen Refactoring-Prozessen arbeiten, die sich beide auf denselben Satz von Dateien auswirken, sollten Sie sich im Voraus miteinander austauschen und herausfinden, welche Arten von Änderungen Sie jeweils vornehmen Herstellung. Sie können viel Zeit und Aufwand sparen, wenn Sie Ihre geplanten Änderungen seriell und nicht parallel durchführen.

Bei größeren Refactorings, die einen großen Teil des Codes durchlaufen, sollten Sie ernsthaft in Erwägung ziehen, seriell zu arbeiten: Jeder arbeitet an diesem Codebereich, während eine Person das komplette Refactoring durchführt.

Wenn Sie nicht in der Lage sind, seriell zu arbeiten (aufgrund von Zeitdruck, vielleicht), dann hilft zumindest die Kommunikation über erwartete Konflikte bei der Zusammenführung Sie die Probleme schneller zu lösen, während die Details noch frisch sind. Wenn beispielsweise ein Mitarbeiter im Verlauf eines einwöchigen Zeitraums eine unterbrechende Serie von Commits durchführt, können Sie in dieser Woche ein- oder zweimal pro Tag den Zweig "Mitarbeiter" ein- oder zweimal zusammenführen. Auf diese Weise können Sie Konflikte lösen, wenn Sie Merge / Rebase-Konflikte finden, die schneller gelöst werden können, als wenn Sie ein paar Wochen warten, um alles zu einem großen Ganzen zusammenzufügen.

Tipp fünf

Wenn Sie sich bei einer Zusammenführung nicht sicher sind, erzwingen Sie sie nicht.

Das Zusammenführen kann überwältigend sein, besonders wenn es viele widersprüchliche Dateien gibt und die Konfliktmarker Hunderte von Zeilen umfassen. Bei der Schätzung von Softwareprojekten wird oft nicht genügend Zeit für Overhead-Elemente wie die Bearbeitung einer knappen Verschmelzung eingeplant, so dass es sich wie ein echter Zeitvertreib anfühlt, mehrere Stunden lang jeden Konflikt zu analysieren.

Auf lange Sicht können Sie vorausschauend planen und sich bewusst sein, woran andere arbeiten. Dies sind die besten Werkzeuge, um Zusammenführungskonflikte zu antizipieren und sich darauf vorzubereiten, sie in kürzerer Zeit korrekt zu lösen.


683
2017-09-28 21:08



  1. Identifizieren Sie, welche Dateien in Konflikt sind (Git sollte Ihnen das sagen).

  2. Öffnen Sie jede Datei und untersuchen Sie die Diffs. Git grenzt sie ab. Hoffentlich wird es offensichtlich sein, welche Version von jedem Block zu behalten ist. Möglicherweise müssen Sie dies mit anderen Entwicklern besprechen, die den Code festgelegt haben.

  3. Sobald Sie den Konflikt in einer Datei gelöst haben git add the_file.

  4. Sobald Sie das Problem gelöst haben alle Konflikte, tun git rebase --continue oder welcher Befehl auch immer Git sagte zu tun, wenn Sie fertig waren.


321
2017-10-02 12:41



Sehen Sie sich die Antworten in der Frage zum Stack-Überlauf an Eine Zusammenführung in Git wird abgebrochen, insbesondere Charles Baileys Antwort zeigt, wie Sie die verschiedenen Versionen der Datei mit Problemen anzeigen, z. B.

# Common base version of the file.
git show :1:some_file.cpp

# 'Ours' version of the file.
git show :2:some_file.cpp

# 'Theirs' version of the file.
git show :3:some_file.cpp

97
2017-10-03 15:15



Zusammenführungskonflikte treten auf, wenn gleichzeitig Änderungen an einer Datei vorgenommen werden. Hier ist, wie man es löst.

git CLI

Hier sind einfache Schritte, was zu tun ist, wenn Sie in Konflikt geraten:

  1. Notieren Sie die Liste der konfliktbehafteten Dateien mit: git status (unter Unmerged paths Sektion).
  2. Lösen Sie die Konflikte für jede Datei einzeln durch einen der folgenden Ansätze:

    • Benutze GUI, um die Konflikte zu lösen: git mergetool (der einfachste Weg).

    • Um Remote / andere Version zu akzeptieren, verwenden Sie: git checkout --theirs path/file. Dadurch werden alle lokalen Änderungen zurückgewiesen, die Sie für diese Datei vorgenommen haben.

    • Um lokale / unsere Version zu akzeptieren, verwenden Sie: git checkout --ours path/file

      Sie müssen jedoch vorsichtig sein, da entfernte Konflikte aus irgendeinem Grund Konflikte verursacht haben.

      Verbunden: Was genau bedeutet "unsere" und "ihre" in git?

    • Bearbeiten Sie die konfliktbehafteten Dateien manuell und suchen Sie nach dem Codeblock zwischen <<<<</>>>>> Wählen Sie dann die Version entweder von oben oder von unten =====. Sehen: Wie Konflikte dargestellt werden.

    • Pfad- und Dateinamenskonflikte können durch gelöst werden git add/git rm.

  3. Überprüfen Sie abschließend die Dateien, die zum Festschreiben bereit sind, mithilfe von: git status.

    Wenn Sie noch irgendwelche Dateien unter haben Unmerged paths, und Sie haben den Konflikt manuell gelöst, dann lassen Sie Git wissen, dass Sie es gelöst haben, indem Sie: git add path/file.

  4. Wenn alle Konflikte erfolgreich gelöst wurden, übernehmen Sie die Änderungen wie folgt: git commit -a und drücken Sie wie gewohnt auf die Fernbedienung.

Siehe auch: Auflösen eines Zusammenführungskonflikts über die Befehlszeile bei GitHub

DiffMerge

Ich habe erfolgreich verwendet DiffMerge mit denen Sie Dateien unter Windows, Mac OS und Linux / Unix visuell vergleichen und zusammenführen können.

Es kann grafisch die Änderungen zwischen 3 Dateien zeigen und erlaubt die automatische Zusammenführung (wenn dies sicher ist) und die volle Kontrolle über die Bearbeitung der resultierenden Datei.

DiffMerge

Bildquelle: DiffMerge (Linux-Screenshot)

Einfach herunterladen und in Repo laufen als:

git mergetool -t diffmerge .

Mac OS

Auf MacOS können Sie installieren über:

brew install caskroom/cask/brew-cask
brew cask install diffmerge

Und wahrscheinlich (wenn nicht bereitgestellt) benötigen Sie den folgenden zusätzlichen einfachen Wrapper, der in Ihrem PATH (z. /usr/bin):

#!/bin/sh
DIFFMERGE_PATH=/Applications/DiffMerge.app
DIFFMERGE_EXE=${DIFFMERGE_PATH}/Contents/MacOS/DiffMerge
exec ${DIFFMERGE_EXE} --nosplash "$@"

Dann können Sie die folgenden Tastenkombinationen verwenden:

  • -Alt-Oben/Nieder um zur vorherigen / nächsten Änderung zu springen.
  • -Alt-Links/Recht Änderungen von links oder rechts zu akzeptieren

Alternativ können Sie verwenden Opendiff (Teil von Xcode Tools), mit dem Sie zwei Dateien oder Verzeichnisse zusammenführen können, um eine dritte Datei oder ein drittes Verzeichnis zu erstellen.


88
2017-08-05 14:29



Wenn Sie häufig kleine Commits machen, dann sehen Sie sich zunächst die Commit-Kommentare an git log --merge. Dann git diff zeigt dir die Konflikte.

Bei Konflikten, die mehr als ein paar Zeilen umfassen, ist es einfacher zu sehen, was in einem externen GUI-Tool vor sich geht. Ich mag opendiff - Git unterstützt auch vimdiff, gvimdiff, kdiff3, tkdiff, meld, xxdiff, entstehen aus der Box und Sie können andere installieren: git config merge.tool "your.tool" wird das gewählte Werkzeug einstellen und dann git mergetool Nach einer fehlgeschlagenen Zusammenführung werden Ihnen die Unterschiede im Kontext angezeigt.

Jedes Mal, wenn Sie eine Datei bearbeiten, um einen Konflikt zu lösen, git add filename aktualisiert den Index und dein Diff wird ihn nicht mehr anzeigen. Wenn alle Konflikte bearbeitet und ihre Dateien bearbeitet wurden git add-ed, git commit wird deine Zusammenführung vervollständigen.


73
2017-10-02 16:11



Sehen Wie Konflikte präsentiert werden oder, in Git, der git merge Dokumentation, um zu verstehen, welche Merge-Konflikt-Marker sind.

Auch der Wie man Konflikte löst Abschnitt erklärt, wie Sie die Konflikte lösen können:

Nachdem Sie einen Konflikt gesehen haben, können Sie zwei Dinge tun:

  • Entscheide dich nicht zu verschmelzen. Die einzigen Bereinigungen, die Sie benötigen, sind das Zurücksetzen der Indexdatei auf die HEAD verpflichten sich, 2. umzukehren und Arbeitsbaumänderungen zu bereinigen, die von 2. und 3. gemacht wurden; git merge --abort kann dafür verwendet werden.

  • Löse die Konflikte. Git markiert die Konflikte im Arbeitsbaum. Bearbeiten Sie die Dateien in Form und git add sie zum Index. Benutzen git commit um den Deal zu besiegeln.

Sie können den Konflikt mit einer Reihe von Werkzeugen bearbeiten:

  • Verwenden Sie ein Mergtool. git mergetool Starten eines grafischen Mergetools, das Sie durch die Zusammenführung führt.

  • Schau dir die Diffs an. git diff zeigt ein Drei-Wege-Diff und hebt Änderungen aus beiden hervor HEAD und MERGE_HEAD Versionen.

  • Schau dir die Diffs von jedem Zweig an. git log --merge -p <path> wird Diffs zuerst für die anzeigen HEAD Version und dann die MERGE_HEAD Ausführung.

  • Sieh dir die Originale an. git show :1:filename zeigt den gemeinsamen Vorfahren, git show :2:filename zeigt die HEAD Version und git show :3:filename zeigt die MERGE_HEAD Ausführung.

Sie können auch über Merge-Konfliktmarker lesen und erfahren, wie Sie sie in der Pro Git Buchabteilung Grundlegende Zusammenführungskonflikte.


43
2017-07-14 18:34



Zum Emacs Benutzer, die Merge-Konflikte halbautomatisch lösen möchten:

git diff --name-status --diff-filter=U

zeigt alle Dateien an, die eine Konfliktlösung erfordern.

Öffnen Sie jede dieser Dateien nacheinander oder auf einmal:

emacs $(git diff --name-only --diff-filter=U)

Wenn Sie einen Puffer aufrufen, der in Emacs bearbeitet werden muss, geben Sie Folgendes ein

ALT+x vc-resolve-conflicts

Dies öffnet drei Puffer (meins, deren und den Ausgabepuffer). Navigieren Sie durch Drücken von 'n' (nächste Region), 'p' (Region der Voraussicht). Drücken Sie 'a' und 'b', um meine bzw. ihre Region in den Ausgabepuffer zu kopieren. Und / oder bearbeiten Sie den Ausgabepuffer direkt.

Wenn fertig: Drücken Sie 'q'. Emacs fragt Sie, ob Sie diesen Puffer speichern möchten: ja. Nachdem Sie einen Puffer beendet haben, markieren Sie ihn wie folgt:

git add FILENAME

Wenn Sie mit allen Puffern fertig sind

git commit

um die Zusammenführung zu beenden.


36
2018-02-22 23:04



Befolgen Sie die folgenden Schritte, um Zusammenführungskonflikte in Git zu beheben:

  1. Überprüfen Sie den Git Status: Git Status

  2. Holen Sie sich das Patchset: git holen (Überprüfe den rechten Patch von deinem Git Commit)

  3. Prüfe einen lokalen Zweig (temp1 in meinem Beispiel hier): git checkout -b temp1

  4. Ziehen Sie die aktuellen Inhalte aus dem Master: Git Pull - Rebase Herkunft Meister

  5. Starten Sie das Mergetool und überprüfen Sie die Konflikte und beheben Sie diese ... und überprüfen Sie die Änderungen in der Remote-Verzweigung mit Ihrer aktuellen Verzweigung: Git mergetool

  6. Überprüfen Sie den Status erneut:   Git Status

  7. Löschen Sie die unerwünschten Dateien, die lokal von mergetool erstellt wurden. Normalerweise erstellt mergetool zusätzliche Dateien mit der Erweiterung * .orig. Bitte löschen Sie diese Datei, da dies nur das Duplikat ist und korrigieren Sie Änderungen lokal und fügen Sie die korrekte Version Ihrer Dateien hinzu. git add #your_changed_correct_files

  8. Überprüfen Sie den Status erneut: Git Status

  9. Übergeben Sie die Änderungen an dieselbe Commit-ID (dies vermeidet einen neuen separaten Patch-Satz): git commit --amend

  10. Drücken Sie auf den Master-Zweig: Git drücken (zu deinem Git Repository)


28
2018-04-16 07:02