it-swarm.com.de

So lösen Sie Zusammenführungskonflikte in Git

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

4303
Spoike

Versuchen Sie: git mergetool

Es öffnet sich eine GUI, die Sie schrittweise durch die einzelnen Konflikte führt, und Sie können auswählen, wie die Zusammenführung erfolgen soll. Manchmal erfordert es nachträglich ein wenig Handbearbeitung, aber normalerweise reicht es für sich aus. Es ist viel besser, als das Ganze sicher von Hand zu machen.

Wie im Kommentar von @JoshGlover:

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

Im Folgenden finden Sie die Beispielprozedur für die Verwendung von vimdiff zum Auflösen von Zusammenführungskonflikten. Basierend auf diesem Link

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

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

Dadurch wird vimdiff als Standardwerkzeug für die Zusammenführung festgelegt.

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

git mergetool

Schritt 3: Sie sehen eine Vimdiff-Anzeige in folgendem Format 

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

Diese 4 Ansichten sind 

LOCAL - Dies ist eine Datei aus dem aktuellen Zweig 

BASE - gemeinsamer Vorfahre, wie die Datei vor beiden Änderungen aussah 

REMOTE - Datei, die Sie in Ihrem Zweig zusammenführen 

MERGED - Zusammenführungsergebnis, dies wird im Repo gespeichert

Sie können mit ctrl+w zwischen diesen Ansichten navigieren. Sie erreichen die MERGED-Ansicht direkt mit ctrl+w, gefolgt von j.

Mehr Infos über vimdiff navigation 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, bestätigen und bereinigen

:wqa speichern und von vi beenden

git commit -m "message"

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

2569
Peter Burns

Hier ist ein wahrscheinlicher Anwendungsfall von oben:

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

git fetch Origin
git pull Origin master

From ssh://[email protected]:22/projectname
 * branch            master     -> FETCH_HEAD
Updating a030c3a..ee25213
error: Entry 'filename.c' not uptodate. Cannot merge.

Sie werden also auf dem neuesten Stand und versuchen es erneut, haben jedoch einen Konflikt:

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

From ssh://[email protected]: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 für einen Blick auf die Änderungen:

git mergetool

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

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

Und dann versuchen wir es ein letztes Mal

git pull Origin master

From ssh://[email protected]:22/projectname
 * branch            master     -> FETCH_HEAD
Already up-to-date.

Ta-da!

1631
CoolAJ86

Ich finde, Merge-Tools helfen mir selten, den Konflikt oder die Lösung zu verstehen. Ich bin in der Regel erfolgreicher, wenn ich die Konfliktmarker in einem Texteditor anschaue und git log als Ergänzung nehme.

Hier sind ein paar Tipps:

Tipp eins

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

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.
>>>>>>>

Im Mittelteil sah der gemeinsame Vorfahr aus. Dies ist nützlich, da Sie es mit der oberen und der unteren Version vergleichen können, um ein besseres Verständnis dafür zu erhalten, was in jedem Zweig geändert wurde. Dadurch erhalten Sie eine bessere Vorstellung davon, was der Zweck jeder Änderung war.

Wenn der Konflikt nur aus wenigen Zeilen besteht, wird der Konflikt im Allgemeinen sehr offensichtlich. (Zu wissen, wie ein Konflikt gelöst werden kann, ist etwas ganz anderes. Sie müssen wissen, woran andere Leute arbeiten. Wenn Sie verwirrt sind, ist es am besten, wenn Sie diese Person in Ihrem Zimmer anrufen, damit sie sehen können, was Sie suchen beim.)

Wenn der Konflikt länger dauert, werde ich jeden der drei Abschnitte ausschneiden und in drei separate Dateien einfügen, z. B. "meine", "gemeinsame" und "ihre".

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

diff common mine
diff common theirs

Dies ist nicht dasselbe wie das Verwenden eines Merge-Tools, da ein Merge-Tool auch alle nicht konfliktbehafteten Unterschiede enthält. Ich finde das ablenkend.

Tipp zwei

Jemand hat dies bereits erwähnt, aber das Verständnis der Absicht hinter jedem Unterschied ist in der Regel sehr hilfreich, um zu verstehen, woher ein Konflikt kam und wie er damit umgehen sollte.

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

Hier werden alle Commits angezeigt, die diese Datei zwischen dem gemeinsamen Vorfahren und den beiden Köpfen, die Sie zusammenführen, berührt haben. (Daher sind keine Commits enthalten, die vor dem Zusammenführen in beiden Zweigen bereits vorhanden sind.) Dies hilft Ihnen, Unterschiede zu ignorieren, die eindeutig keinen Einfluss auf Ihren aktuellen Konflikt haben.

Tipp drei

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

Wenn Sie automatisierte Tests durchgeführt haben, führen Sie diese aus. Wenn Sie ein lint haben, führen Sie das aus. Wenn es sich um ein erstellbares Projekt handelt, erstellen Sie es vor dem Festschreiben usw. In jedem Fall müssen Sie ein wenig testen, um sicherzustellen, dass Ihre Änderungen nichts kaputt machen. (Heck, sogar eine Zusammenführung ohne Konflikte kann den Arbeitscode beschädigen.)

Tipp vier

Vorausplanen; mit Kollegen kommunizieren.

Vorausplanen und wissen, woran andere arbeiten, kann dazu beitragen, Zusammenführungskonflikte zu vermeiden und/oder sie früher zu lösen - während die Details noch frisch sind. 

Wenn Sie zum Beispiel wissen, dass Sie und eine andere Person an unterschiedlichen Refactoring-Vorgängen arbeiten, die sich auf denselben Dateisatz auswirken, sollten Sie sich vorab mit den anderen besprechen und ein besseres Verständnis dafür bekommen, welche Art von Änderung jeder von Ihnen ist Herstellung. Sie können viel Zeit und Mühe sparen, wenn Sie Ihre geplanten Änderungen seriell statt parallel durchführen. 

Bei großen Refactorings, die einen großen Codebereich durchlaufen, sollten Sie unbedingt seriell arbeiten: Jeder hört auf, in diesem Codebereich zu arbeiten, während eine Person das komplette Refactoring durchführt.

Wenn Sie nicht seriell arbeiten können (möglicherweise aufgrund von Zeitdruck), hilft Ihnen die Kommunikation über erwartete Zusammenführungskonflikte zumindest, wenn Sie die Probleme früher lösen, während die Details noch im Hinterkopf sind. Wenn z. B. ein Mitarbeiter im Verlauf eines Zeitraums von einer Woche störende Commits eingeht, können Sie sich in dieser Woche ein- oder zweimal täglich auf dieser Zweigstelle zusammenlegen. Auf diese Weise können Sie Konflikte beim Zusammenführen/Wiederherstellen schneller lösen, als wenn Sie einige Wochen warten, um alles zu einem großen Klumpen zusammenzufügen.

Tipp fünf

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

Das Zusammenführen kann sich überwältigend anfühlen, insbesondere wenn viele Dateien in Konflikt stehen und die Konfliktmarkierungen Hunderte von Zeilen umfassen. Bei der Schätzung von Softwareprojekten nehmen wir oft nicht genügend Zeit für Overhead-Elemente ein, wie z. B. die Durchführung einer gnarly merge, und es fühlt sich wie ein echter Widerstand an, mehrere Stunden damit zu verbringen, jeden Konflikt zu analysieren.

Langfristig zu planen und sich bewusst zu machen, woran andere arbeiten, ist das beste Werkzeug, um Zusammenführungskonflikte zu antizipieren und sich darauf vorzubereiten, sie in kürzerer Zeit richtig zu lösen.

700
Mark E. Haase
  1. Identifizieren Sie, welche Dateien in Konflikt sind (Git sollte Ihnen dies mitteilen).

  2. Öffnen Sie jede Datei und untersuchen Sie die Unterschiede. Git grenzt sie ab. Hoffentlich ist es offensichtlich, welche Version jedes Blocks beibehalten werden soll. Möglicherweise müssen Sie dies mit anderen Entwicklern besprechen, die den Code festgelegt haben.

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

  4. Sobald Sie all - Konflikte gelöst haben, führen Sie git rebase --continue oder einen beliebigen anderen Befehl aus.

328
davetron5000

Lesen Sie die Antworten in der Stack Overflow-Frage Abbruch einer Zusammenführung in Git, insbesondere Charles Baileys Antwort die zeigt, wie die verschiedenen Versionen der Datei mit Problemen angezeigt werden 

# 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
101
Pat Notz

Zusammenführungskonflikte treten auf, wenn gleichzeitig Änderungen an einer Datei vorgenommen werden. Hier erfahren Sie, wie Sie das Problem lösen können.

git CLI

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

  1. Beachten Sie die Liste der in Konflikt stehenden Dateien mit: git status (im Abschnitt Unmerged paths).
  2. Lösen Sie die Konflikte für jede Datei separat auf eine der folgenden Arten:

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

    • Verwenden Sie git checkout --theirs path/file, um eine entfernte/andere Version zu akzeptieren. Dadurch werden alle lokalen Änderungen, die Sie für diese Datei vorgenommen haben, verworfen.

    • Verwenden Sie zum Akzeptieren der lokalen/unserer Version: git checkout --ours path/file

      Sie müssen jedoch vorsichtig sein, da Remote-Änderungen aus irgendeinem Grund zu Konflikten geführt haben.

      Verwandte: Was ist die genaue Bedeutung von "uns" und "ihnen" in git?

    • Bearbeiten Sie die in Konflikt stehenden Dateien manuell und suchen Sie nach dem Codeblock zwischen <<<<</>>>>>. Wählen Sie dann die Version entweder über oder unter =====. Siehe: Wie Konflikte dargestellt werden .

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

  3. Überprüfen Sie abschließend die festschreibungsbereiten Dateien mit: git status.

    Wenn unter Unmerged paths noch Dateien vorhanden sind und Sie den Konflikt manuell gelöst haben, teilen Sie Git mit, dass Sie ihn folgendermaßen gelöst haben: git add path/file.

  4. Wenn alle Konflikte erfolgreich gelöst wurden, übernehmen Sie die Änderungen wie gewohnt mit: git commit -a und Push to remote.

Siehe auch: Beheben eines Zusammenführungskonflikts über die Befehlszeile at GitHub

DiffMerge

Ich habe erfolgreich DiffMerge verwendet, das Dateien unter Windows, macOS und Linux/Unix visuell vergleichen und zusammenführen kann.

Es kann die Änderungen zwischen 3 Dateien grafisch darstellen und ermöglicht das automatische Zusammenführen (wenn dies sicher ist) und die vollständige Kontrolle über die Bearbeitung der resultierenden Datei.

DiffMerge

Bildquelle: DiffMerge (Linux-Screenshot)

Einfach herunterladen und in repo ausführen als:

git mergetool -t diffmerge .

mac OS

Unter macOS können Sie installieren über:

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

Und wahrscheinlich (falls nicht angegeben) benötigen Sie den folgenden besonders einfachen Wrapper in Ihrem PATH (z. B. /usr/bin):

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

Dann können Sie die folgenden Tastaturkürzel verwenden:

  • -Alt-Up/Down um zu vorherigen/nächsten Änderungen zu springen.
  • -Alt-Left/Right Wechsel von links oder rechts akzeptieren

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

90
kenorb

Wenn Sie häufige Small Commits durchführen, schauen Sie sich zunächst die Commit-Kommentare mit git log --merge an. Dann zeigt Ihnen git diff die Konflikte.

Bei Konflikten, die mehr als ein paar Zeilen umfassen, ist es einfacher zu erkennen, was in einem externen GUI-Tool passiert. Ich mag opendiff - Git unterstützt auch vimdiff, gvimdiff, kdiff3, tkdiff, meld, xxdiff, ist out of the box und Sie können andere installieren: git config merge.tool "your.tool" setzt das gewählte Werkzeug und dann zeigt git mergetool nach einer fehlgeschlagenen Zusammenführung die Unterschiede an Kontext.

Jedes Mal, wenn Sie eine Datei bearbeiten, um einen Konflikt zu lösen, aktualisiert git add filename den Index und Ihr Diff zeigt ihn nicht mehr an. Wenn alle Konflikte behandelt und ihre Dateien git add- behandelt wurden, wird git commit die Zusammenführung abschließen.

76
Paul

Siehe Darstellung von Konflikten oder in Git die git merge-Dokumentation, um zu verstehen, was Zusammenführungskonfliktmarken sind.

Im Abschnitt So lösen Sie Konflikte auf erfahren Sie, wie Sie 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 HEAD, um die Umkehrung von 2. und Bereinigung der von 2. und 3 vorgenommenen Änderungen in der Arbeitsstruktur durchzuführen .; Hierfür kann git merge --abort verwendet werden.

  • Lösen Sie die Konflikte. Git markiert die Konflikte im Arbeitsbaum. Bearbeiten Sie die Dateien in Form und git add sie in den Index. Verwenden Sie git commit, um das Geschäft abzuschließen.

Sie können den Konflikt mit einer Reihe von Tools durcharbeiten:

  • Verwenden Sie ein Mergetool. git mergetool, um ein grafisches Mergetool zu starten, das Sie durch die Zusammenführung führt.

  • Schau dir die Unterschiede an. git diff zeigt einen Drei-Wege-Vergleich an, der Änderungen der Versionen HEAD und MERGE_HEAD hervorhebt.

  • Schauen Sie sich die Unterschiede von jedem Zweig an. git log --merge -p <path> zeigt zuerst die Unterschiede für die HEAD-Version und dann die MERGE_HEAD-Version an.

  • Schauen Sie sich 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-Version.

Informationen zum Zusammenführen von Konfliktmarken und deren Behebung finden Sie im Abschnitt Pro Git book Basic Merge Conflicts .

44
user456814

Für Emacs Benutzer, die Zusammenführungskonflikte halb manuell lösen möchten:

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

zeigt alle Dateien an, für die eine Konfliktlösung erforderlich ist.

Öffnen Sie jede dieser Dateien nacheinander oder alle auf einmal durch:

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

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

ALT+x vc-resolve-conflicts

Dadurch werden drei Puffer geöffnet (meine, ihre und der Ausgabepuffer). Navigieren Sie durch Drücken von 'n' (nächster Bereich) und 'p' (vorheriger Bereich). Drücken Sie 'a' und 'b', um meine oder ihre Region in den Ausgabepuffer zu kopieren. Und/oder den Ausgabepuffer direkt bearbeiten.

Wenn Sie fertig sind: Drücken Sie 'q'. Emacs fragt Sie, ob Sie diesen Puffer speichern möchten: yes . Nachdem Sie einen Puffer beendet haben, markieren Sie ihn als gelöst, indem Sie vom Puffer aus laufen:

git add FILENAME

Wenn Sie mit allen Puffern fertig sind

git commit

die Verschmelzung beenden.

37
eci

Ich möchte entweder meine oder ihre Version vollständig oder möchte einzelne Änderungen überprüfen und für jede einzelne entscheiden.

Akzeptiere meine oder ihre Version vollständig :

Akzeptiere meine Version (lokal, unsere):

git checkout --ours -- <filename>
git add <filename>              # Marks conflict as resolved
git commit -m "merged bla bla"  # An "empty" commit

Akzeptieren Sie ihre Version (Remote, ihre):

git checkout --theirs -- <filename>
git add <filename>
git commit -m "merged bla bla"

Wenn Sie für alle Konfliktdateien ausführen möchten, ausführen:

git merge --strategy-option ours

oder

git merge --strategy-option theirs

Überprüfe alle Änderungen und akzeptiere sie einzeln

  1. git mergetool
  2. Überprüfen Sie die Änderungen und akzeptieren Sie für beide Versionen eine der beiden Versionen.
  3. git add <filename>
  4. git commit -m "merged bla bla"

Standardeinstellung mergetool funktioniert in Befehlszeile . Wie man ein Befehlszeilen-Mergetool verwendet, sollte eine separate Frage sein.

Sie können auch visual tool dafür installieren, z. meld und ausführen

git mergetool -t meld

Es wird die lokale Version (unsere), die "Basisversion" oder "Zusammenführungsversion" (das aktuelle Ergebnis der Zusammenführung) und die Remote-Version (ihre Version) geöffnet. Speichern Sie die zusammengeführte Version, wenn Sie fertig sind, führen Sie git mergetool -t meld erneut aus, bis "Keine Dateien müssen zusammengeführt werden". Fahren Sie dann mit Schritt 3 und 4 fort.

31
Noidea

Bitte 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 fetch (überprüfen Sie den richtigen Patch von Ihrem Git-Commit)

  3. Checke einen lokalen Zweig aus (temp1 in meinem Beispiel hier): git checkout -b temp1

  4. Ziehen Sie die letzten Inhalte vom Master: git pull --rebase Origin master

  5. Starte das mergetool und überprüfe die Konflikte und behebe sie ... und überprüfe die Änderungen im entfernten Zweig mit deinem aktuellen Zweig: git mergetool

  6. Überprüfen Sie den Status erneut: git status

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

  8. Überprüfen Sie den Status erneut: git status

  9. Übernehmen Sie die Änderungen in dieselbe Festschreibungs-ID (dies vermeidet ein neues separates Patch-Set): git commit --amend

  10. Push to the master branch: git Push (in dein Git-Repository)

28
Chhabilal

Wenn Sie genau wissen, dass Änderungen in einem der Repositorys nicht wichtig sind und alle Änderungen zu Gunsten des anderen auflösen möchten, verwenden Sie Folgendes:

git checkout . --ours

Änderungen zu Gunsten von Ihrem Repository oder auflösen

git checkout . --theirs

Änderungen zu Gunsten des anderen oder des Hauptdepuments auflösen .

Oder Sie müssen ein GUI-Merge-Tool verwenden, um die Dateien nacheinander zu durchlaufen, sagen Sie, das Merge-Tool ist p4merge, oder schreiben Sie einen beliebigen Namen, den Sie bereits installiert haben

git mergetool -t p4merge

nach dem Beenden einer Datei müssen Sie speichern und schließen, damit die nächste geöffnet wird.

27
Mohamed Selim

Bonus:

Wenn ich in den obigen Antworten von Pull/Fetch/Merge spreche, möchte ich einen interessanten und produktiven Trick teilen:

git pull --rebase

Dieser Befehl ist der nützlichste Befehl in meinem Git-Leben, der viel Zeit gespart hat.

Bevor Sie die neu festgeschriebene Änderung auf den Remote-Server übertragen, probieren Sie git pull --rebase und nicht git pull und manuell merge. Die letzten Remote-Server-Änderungen werden automatisch synchronisiert (mit Fetch + Merge) und Ihr lokaler letzter Commit wird im git-Protokoll oben angezeigt. Sie müssen sich keine Gedanken über manuelles Ziehen/Zusammenführen machen.

Im Konfliktfall einfach verwenden 

git mergetool
git add conflict_file
git rebase --continue

Details finden Sie unter: http://gitolite.com/git-pull--rebase

26

Sie können Zusammenführungskonflikte auf verschiedene Arten beheben, wie andere ausführlich beschrieben haben.

Ich denke, der eigentliche Schlüssel ist zu wissen, wie Änderungen mit lokalen und Remote-Repositories ablaufen. Der Schlüssel dazu ist das Verfolgen von Zweigen. Ich habe festgestellt, dass ich den Tracking-Zweig als das "fehlende Stück in der Mitte" sehe, zwischen meinem lokalen, aktuellen Dateiverzeichnis und dem als Origin definierten Remote. 

Ich habe mich daran gewöhnt, zwei Dinge zu tun, um dies zu vermeiden.

Anstatt:

git add .
git commit -m"some msg"

Was hat zwei Nachteile - 

a) Alle neuen/geänderten Dateien werden hinzugefügt und dies kann einige unerwünschte Änderungen enthalten.
b) Sie können die Dateiliste nicht zuerst überprüfen.

Stattdessen mache ich:

git add file,file2,file3...
git commit # Then type the files in the editor and save-quit.

Auf diese Weise sind Sie bewusster darüber, welche Dateien hinzugefügt werden, und Sie können auch die Liste überprüfen und ein wenig mehr darüber nachdenken, während Sie den Editor für die Nachricht verwenden. Ich finde, es verbessert auch meine Commit-Nachrichten, wenn ich einen Vollbild-Editor anstelle der -m-Option verwende.

[Update - Mit der Zeit habe ich mehr zu:

git status # Make sure I know whats going on
git add .
git commit # Then use the editor

]

Auch (und relevanter für Ihre Situation) versuche ich zu vermeiden:

git pull

oder

git pull Origin master.

weil pull eine Zusammenführung impliziert und wenn Sie lokal Änderungen haben, die Sie nicht zusammengeführt haben möchten, können Sie leicht mit zusammengeführtem Code enden und/oder Konflikte für Code zusammenführen, der nicht zusammengeführt werden sollte.

Stattdessen versuche ich es zu tun

git checkout master
git fetch   
git rebase --hard Origin/master # or whatever branch I want.

Sie können dies auch hilfreich finden:

git branch, fork, fetch, merge, rebase und clone, was sind die unterschiede?

25
Michael Durrant

Die Antwort von CoolAJ86 fasst so ziemlich alles zusammen. Falls Sie in beiden Abschnitten Änderungen am selben Code-Code vorgenommen haben, müssen Sie eine manuelle Zusammenführung vornehmen. Öffnen Sie die Datei in Konflikt in einem beliebigen Texteditor. Die folgende Struktur sollte angezeigt werden.

(Code not in Conflict)
>>>>>>>>>>>
(first alternative for conflict starts here)
Multiple code lines here
===========
(second alternative for conflict starts here)
Multiple code lines here too    
<<<<<<<<<<<
(Code not in conflict here)

Wählen Sie eine der Alternativen oder eine Kombination aus beiden auf eine Weise, die neuer Code sein soll, während Sie Gleichheitszeichen und spitze Klammern entfernen. 

git commit -a -m "commit message"
git Push Origin master
22
iankit

Es gibt 3 Schritte:

  1. Finden Sie heraus, welche Dateien Konflikte verursachen

    git status
    
  2. Überprüfen Sie die Dateien, in denen Sie die Konflikte wie markiert finden würden

    <<<<<<<<head
    blablabla
    
  3. Ändern Sie es so, wie Sie es möchten, und bestätigen Sie es mit Befehlen

    git add solved_conflicts_files
    git commit -m 'merge msg'
    
20
Qijun Liu
git log --merge -p [[--] path]

Scheint nicht immer für mich zu funktionieren und zeigt in der Regel jedes Commit an, das zwischen den beiden Zweigen unterschiedlich war. Dies geschieht auch, wenn Sie den Pfad mit -- vom Befehl trennen.

Um dieses Problem zu umgehen, müssen zwei Befehlszeilen und in einem Durchgang geöffnet werden

git log ..$MERGED_IN_BRANCH --pretty=full -p [path]

und in der anderen

git log $MERGED_IN_BRANCH.. --pretty=full -p [path]

Ersetzen von $MERGED_IN_BRANCH durch den Zweig, in den ich mich verschmolz, und [path] durch die Datei, die in Konflikt steht. Dieser Befehl protokolliert alle Commits in Patch-Form zwischen (..) zwei Commits. Wenn Sie eine Seite wie in den obigen Befehlen leer lassen, verwendet git automatisch HEAD (den Zweig, in dem Sie in diesem Fall eine Verbindung herstellen).

Auf diese Weise können Sie sehen, welche Commits in den beiden Zweigen in die Datei eingegangen sind, nachdem sie voneinander abweichen. In der Regel ist es viel einfacher, Konflikte zu lösen.

15
Brian Di Palma

patience verwenden

Ich bin überrascht, dass niemand sonst über die Konfliktlösung unter Verwendung von patience mit der rekursiven Zusammenführungsstrategie gesprochen hat. Bei einem großen Verschmelzungskonflikt lieferte die Verwendung von patience gute Ergebnisse für mich. Die Idee ist, dass versucht wird, Blöcke statt einzelner Zeilen zuzuordnen.

Wenn Sie beispielsweise die Einrückung Ihres Programms ändern, entspricht die standardmäßige Git-Merge-Strategie manchmal einzelnen Klammern {, die zu verschiedenen Funktionen gehören. Dies wird mit patience vermieden:

git merge -s recursive -X patience other-branch

Aus der Dokumentation:

With this option, merge-recursive spends a little extra time to avoid 
mismerges that sometimes occur due to unimportant matching lines 
(e.g., braces from distinct functions). Use this when the branches to 
be merged have diverged wildly.

Vergleich mit dem gemeinsamen Vorfahren

Wenn Sie einen Verschmelzungskonflikt haben und wissen möchten, was andere Personen beim Ändern ihres Zweigs vor Augen haben, ist es manchmal einfacher, ihren Zweig direkt mit dem gemeinsamen Vorfahren (anstelle unseres Zweigs) zu vergleichen. Dafür können Sie merge-base verwenden:

git diff $(git merge-base <our-branch> <their-branch>) <their-branch>

Normalerweise möchten Sie nur die Änderungen für eine bestimmte Datei anzeigen:

git diff $(git merge-base <our-branch> <their-branch>) <their-branch> <file>
15
Conchylicultor

Ab dem 12. Dezember 2016 können Sie Zweigstellen zusammenführen und Konflikte auf github.com lösen.

Wenn Sie also die Befehlszeile oder keine Drittanbieter-Tools, die hier aus älteren Antworten angeboten werdenverwenden möchten, _, verwenden Sie das native GitHub-Tool.

Dieser Blogbeitrag erklärt im Detail, aber die Grundlagen sind, dass beim "Zusammenführen" von zwei Zweigen über die Benutzeroberfläche jetzt die Option "Konflikte lösen" angezeigt wird, mit der Sie zu einem Editor gelangen, mit dem Sie diese Zusammenführung durchführen können Konflikte.

 enter image description here

15
maxwell

Ich folge den folgenden Schritten, um Konflikte zu vermeiden.

  • git checkout master (Kommen Sie zum Master-Zweig)
  • git pull (Aktualisieren Sie Ihren Master, um den neuesten Code zu erhalten)
  • git checkout -b mybranch (Checken Sie einen neuen Zweig aus und beginnen Sie mit der Arbeit an diesem Zweig, damit Ihr Master immer oben im Stamm bleibt.)
  • git add. UND git begehen UND git drücken (in Ihrem lokalen Zweig nach den Änderungen)
  • git checkout master (komm zurück zu deinem master.)

Jetzt können Sie dasselbe tun und so viele lokale Filialen pflegen, wie Sie möchten, und gleichzeitig arbeiten.

12
Chetan

Zusammenführungskonflikte können in verschiedenen Situationen auftreten:

  • Wenn "git fetch" und dann "git merge" ausgeführt wird
  • Wenn "git fetch" und dann "git rebase" ausgeführt wird
  • Beim Ausführen von "git pull" (was tatsächlich einer der oben genannten Bedingungen entspricht)
  • Beim Ausführen von "Git Stash Pop"
  • Wenn Sie Git-Patches anwenden (Commits, die zum Übertragen in Dateien exportiert werden, z. B. per E-Mail)

Sie müssen ein Merit-Tool installieren, das mit Git kompatibel ist, um die Konflikte zu lösen. Ich persönlich benutze KDiff3, und ich fand es schön und praktisch. Sie können die Windows-Version hier herunterladen:

https://sourceforge.net/projects/kdiff3/files/

Übrigens, wenn Sie Git Extensions installieren, gibt es im Setup-Assistenten eine Option zur Installation von Kdiff3.

Dann richten Sie git configs ein, um Kdiff als Mergetool zu verwenden:

$ git config --global --add merge.tool kdiff3
$ git config --global --add mergetool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
$ git config --global --add mergetool.kdiff3.trustExitCode false

$ git config --global --add diff.guitool kdiff3
$ git config --global --add difftool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
$ git config --global --add difftool.kdiff3.trustExitCode false

(Denken Sie daran, den Pfad durch den tatsächlichen Pfad der Kdiff-Exe-Datei zu ersetzen.)

Jedes Mal, wenn Sie auf einen Zusammenführungskonflikt stoßen, müssen Sie nur diesen Befehl ausführen:

$git mergetool

Dann öffnet es den Kdiff3 und versucht zuerst, die Zusammenführungskonflikte automatisch aufzulösen. Die meisten Konflikte werden spontan gelöst, und Sie müssen den Rest manuell beheben.

So sieht Kdiff3 aus:

 Enter image description here

Wenn Sie fertig sind, speichern Sie die Datei, und es wird zur nächsten Datei mit Konflikten weitergegangen, und Sie führen dasselbe erneut aus, bis alle Konflikte gelöst sind.

Um zu überprüfen, ob alles erfolgreich zusammengeführt wurde, führen Sie einfach den Befehl mergetool erneut aus. Sie sollten folgendes Ergebnis erhalten:

$git mergetool
No files need merging
11
akazemis

Wenn Sie vom Zweig (Test) zum Master zusammenführen möchten, können Sie die folgenden Schritte ausführen:

Schritt 1: Gehen Sie zum Zweig

git checkout test

Schritt 2: git pull --rebase Origin master

Schritt 3: Falls Konflikte auftreten, ändern Sie diese Dateien mit diesen Dateien.

Schritt 4: Fügen Sie diese Änderungen hinzu

git add #your_changes_files

Schritt 5: git rebase --continue

Schritt 6: Wenn immer noch ein Konflikt vorliegt, fahren Sie wieder mit Schritt 3 fort. Wenn kein Konflikt vorliegt, führen Sie folgende Schritte aus: git Push Origin +test

Schritt 7: Dann gibt es keinen Konflikt zwischen Test und Master. Sie können die Zusammenführung direkt verwenden.

11
Haimei

Mit diesen Antworten wird eine Alternative für Benutzer von VIM hinzugefügt, wie z. B. ich, die alles im Editor erledigen möchte.


TL; DR

 enter image description here


Tpope entwickelte dieses großartige Plugin für VIM mit dem Namen fugitive . Nach der Installation können Sie :Gstatus ausführen, um die Dateien mit Konflikten zu überprüfen, und :Gdiff, um Git in einer 3-Wege-Kombination zu öffnen. 

Sobald Sie sich in der 3-Wege-Mischung befinden, können Sie mit fugitive die Änderungen aller Zweige erhalten, die Sie auf folgende Weise zusammenführen:

  • :diffget //2, Änderungen vom ursprünglichen Zweig (HEAD) abrufen: 
  • :diffget //3, Änderungen vom zusammenführenden Zweig abrufen: 

Wenn Sie mit dem Zusammenführen der Datei fertig sind, geben Sie im zusammengeführten Puffer :Gwrite ein. Vimcasts hat ein großartiges video veröffentlicht, das diese Schritte ausführlich erklärt.

git holen 
git checkout deine Niederlassung
Git Rebase Meister

In diesem Schritt versuchen Sie, den Konflikt mithilfe Ihrer bevorzugten IDE zu beheben

Sie können diesem Link folgen, um zu überprüfen, wie der Konflikt in der Datei behoben wird
https://help.github.com/articles/resolving-a-merge-conflict- using-the-command-line/

git add
Git Rebase - weiter
git begehen --amend
git Push Origin HEAD: refs/drafts/master (Push wie ein Entwurf)

Jetzt ist alles in Ordnung und Sie werden Ihr Engagement in Gerrit finden

Ich hoffe, dass dies jedem in dieser Angelegenheit helfen wird. 

4
Baini.Marouane

Versuchen Sie die Bearbeitung mit Visual Studio Code, wenn Sie noch nicht ... sind .. Was Sie tun, ist, nachdem Sie das Zusammenführen versucht haben (und in Zusammenführungskonflikten landen). Der VS-Code erkennt automatisch die Zusammenführungskonflikte.

Es kann Ihnen sehr gut helfen, indem Sie zeigen, welche Änderungen an der ursprünglichen vorgenommen wurden und sollten Sie incoming oder akzeptieren 

current change (bedeutet Original vor dem Zusammenführen) '?.

Es hat mir geholfen und es kann auch für Sie funktionieren! 

PS: Es funktioniert nur, wenn Sie git mit Ihrem Code und Visual Studio-Code konfiguriert haben. 

2
Kailash Bhalaki

Ich folge dem untenstehenden Prozess.

Der Prozess zum Beheben von Zusammenführungskonflikten:

  1. Ziehen Sie zuerst das neueste aus dem Zielzweig ab, zu dem Sie den git pull Origin develop einfügen möchten.

  2. Wenn Sie das neueste vom Ziel erhalten, lösen Sie den Konflikt nun manuell in IDE, indem Sie diese zusätzlichen Zeichen löschen.

  3. Führen Sie einen git add aus, um diese bearbeiteten Dateien zur git-Warteschlange hinzuzufügen, sodass sie commit und Push für denselben Zweig sein können, an dem Sie arbeiten.

  4. Führen Sie nach Abschluss von git add einen git commit aus, um die Änderungen zu bestätigen.

  5. Schieben Sie die Änderungen jetzt in Ihren Arbeitszweig um git Push Origin HEAD

Wenn Sie Bitbucket oder GitHub verwenden, wird dies in Ihrer Pull-Anfrage behoben.

1
Aniruddha Das

Wenn Sie intelliJ als IDE verwenden. Versuchen Sie, das übergeordnete Element mit Ihrem Zweig zu verbinden

git checkout <localbranch>
git merge Origin/<remotebranch>

Es werden alle Konflikte so angezeigt

A_MBPro: test anu $ git zusammenführen Origin/Automatisch zusammenführen src/test/Java/com /.../ TestClass.Java CONFLICT (Inhalt): Konflikt in .__ zusammenführen. src/test/Java/com /.../ TestClass.Java

Beachten Sie nun, dass die Datei TestClass.Java in intelliJ .__ rot angezeigt wird. Auch der Status der Gitarren wird angezeigt 

Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified:   src/test/Java/com/.../TestClass.Java

Öffnen Sie die Datei in intelliJ, sie enthält Abschnitte mit 

  <<<<<<< HEAD
    public void testMethod() {
    }
    =======
    public void testMethod() { ...
    }
    >>>>>>> Origin/<remotebranch>

dabei ist HEAD Änderungen an Ihrem lokalen Zweig und Origin/Änderungen am entfernten Zweig. Behalten Sie hier das Zeug, das Sie brauchen, und entfernen Sie das, was Sie nicht brauchen. Danach sollten die normalen Schritte ausgeführt werden. Das ist

   git add TestClass.Java
   git commit -m "commit message"
   git Push
1
AJC

Gitlense für VS Code

Sie können Gitlense für VS-Code ausprobieren. Die wichtigsten Funktionen sind:

3. Konflikte einfach lösen.

Ich mag dieses Feature schon:

enter image description here

2. Aktuelle Leitungsverschuldung.

enter image description here

3. Rinne Schuld

enter image description here

4. Statusleiste Schuld

enter image description here

Und es gibt viele Funktionen, die Sie überprüfen können hier .

1
Ilyas karim

Für diejenigen, die Visual Studio verwenden (2015 in meinem Fall)

  1. Schließen Sie Ihr Projekt in VS. Insbesondere in großen Projekten neigt VS dazu, beim Zusammenführen mit der Benutzeroberfläche auszuflippen.

  2. Führen Sie die Zusammenführung in der Eingabeaufforderung aus. 

    git checkout target_branch

    git merge source_branch

  3. Dann öffnen Sie das Projekt in VS und gehen Sie zu Team Explorer -> Branch. Nun gibt es eine Meldung, die besagt, dass die Zusammenführung anhängig ist, und in Konflikt stehende Dateien werden direkt unter der Meldung angezeigt.

  4. Klicken Sie auf die in Konflikt stehende Datei, und Sie haben die Option Zusammenführen, Vergleichen, Quelle übernehmen und Ziel übernehmen. Das Zusammenführungswerkzeug in VS ist sehr einfach zu verwenden.

1
Mike
  1. Erstellen Sie einen neuen Feature-Zweig aus dem Ziel-Zweig
  2. Korrigieren Sie die Änderungen der in Konflikt stehenden Funktionszweige
  3. Lösen Sie Konflikte im Diff-Tool, wenn Sie den Patch anwenden
  4. Clean-Pull-Anforderung bestätigen/überprüfen
  5. Löschen Sie den Zweig, in dem ein Konflikt vorliegt. 

Dies war für mich immer schneller und einfacher als mit Git. Dies ist besonders nützlich, wenn Änderungen eine Pull-Anfrage durcheinanderbringen und Ihre IDE nicht gut mit Git-Merges umgehen kann.

0
git checkout branch1

git fetch Origin

git rebase -p Origin/mainbranch

Wenn es Zusammenführungskonflikte gibt, beheben Sie diese. Fahren Sie dann mit dem Rebase-Prozess fort, indem Sie Folgendes ausführen: git rebase –-continue

nach der Behebung können Sie einen Commit ausführen und Ihren lokalen Zweig in einen entfernten Zweig verschieben

git Push Origin branch1
0

Eine sicherere Methode zur Lösung von Konflikten ist die Verwendung von git-mediate (die hier vorgeschlagenen allgemeinen Lösungen sind ziemlich fehleranfällig).

In diesem Beitrag finden Sie eine kurze Einführung in die Verwendung.

0
yairchu

Ich habe Beyond Compare installiert. Wenn Sie git mergetool verwenden, wird BC gestartet.

0
JasonDiplomat