Wie löse ich Zusammenführungskonflikte in Git?
git
. Hat es heute, 2017, geschafft, die SE-Startseite für mich zu erreichen, mit 1,3 Millionen Views und Tausenden von Stimmen in beide Richtungen. Faszinierend.
Wie löse ich Zusammenführungskonflikte in Git?
git
. Hat es heute, 2017, geschafft, die SE-Startseite für mich zu erreichen, mit 1,3 Millionen Views und Tausenden von Stimmen in beide Richtungen. Faszinierend.
Antworten:
Versuchen: git mergetool
Es öffnet sich eine GUI, die Sie durch jeden Konflikt führt, und Sie können auswählen, wie zusammengeführt werden soll. Manchmal erfordert es danach ein wenig Handbearbeitung, aber normalerweise reicht es für sich. Es ist sicherlich viel besser, als das Ganze von Hand zu machen.
Gemäß @JoshGlover Kommentar:
Der Befehl
öffnet nicht unbedingt eine GUI, es sei denn, Sie installieren eine. Laufen
git mergetool
für mich führte dazu,vimdiff
dass ich benutzt wurde. Sie können eine der folgenden Tools installieren , es zu benutzen , anstatt:meld
,opendiff
,kdiff3
,tkdiff
,xxdiff
,tortoisemerge
,gvimdiff
,diffuse
,ecmerge
,p4merge
,araxis
,vimdiff
,emerge
.
Im Folgenden finden Sie ein Beispielverfahren vimdiff
zur Lösung von Zusammenführungskonflikten. Basierend auf diesem 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-Zusammenführungswerkzeug festgelegt.
Schritt 2 : Führen Sie den 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 - Dies ist eine Datei aus dem aktuellen Zweig
BASE - gemeinsamer Vorfahr, wie die Datei vor beiden Änderungen aussah
REMOTE - Datei, die Sie in Ihren Zweig einfügen
MERGED - Ergebnis zusammenführen, das wird im Repo gespeichert
Sie können mit ctrl+ zwischen diesen Ansichten navigieren w. Sie können die MERGED-Ansicht direkt mit ctrl+ erreichen, wgefolgt von j.
Weitere Infos zur 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, festschreiben und bereinigen
:wqa
Speichern und Beenden von vi
git commit -m "message"
git clean
Entfernen Sie zusätzliche Dateien (z. B. * .orig), die mit dem Diff-Tool erstellt wurden.
git mergetool -y
einige Tastenanschläge speichern, wenn Sie viele Dateien gleichzeitig zusammenführen.
git mergetool
für mich führte dazu, vimdiff
dass ich benutzt wurde. 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
.
git mergetool -t bc3
).
Hier ist ein wahrscheinlicher Anwendungsfall von oben:
Sie werden einige Änderungen vornehmen, aber hoppla, 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.
Sie werden also auf dem neuesten Stand und versuchen es erneut, haben aber einen Konflikt:
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 beschließen also, sich die Änderungen anzusehen:
git mergetool
Oh mein, oh mein, Upstream hat einige Dinge geä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://gitosis@example.com:22/projectname
* branch master -> FETCH_HEAD
Already up-to-date.
Ta-da!
git merge --help
this question
Ich finde, Merge-Tools helfen mir selten, den Konflikt oder die Lösung zu verstehen. Normalerweise bin ich erfolgreicher darin, die Konfliktmarkierungen in einem Texteditor zu betrachten und Git-Protokoll als Ergänzung zu verwenden.
Hier einige Tipps:
Das Beste, was ich gefunden habe, ist die Verwendung des Zusammenführungskonfliktstils "diff3":
git config merge.conflictstyle diff3
Dies erzeugt Konfliktmarkierungen 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 unteren Version vergleichen können, um einen besseren Überblick über die Änderungen in den einzelnen Zweigen zu erhalten. Auf diese Weise erhalten Sie eine bessere Vorstellung davon, welchen Zweck die einzelnen Änderungen hatten.
Wenn der Konflikt nur aus wenigen Zeilen besteht, ist der Konflikt im Allgemeinen sehr offensichtlich. (Zu wissen, wie ein Konflikt behoben werden kann, ist sehr unterschiedlich. Sie müssen sich darüber im Klaren sein, woran andere Personen arbeiten. Wenn Sie verwirrt sind, ist es wahrscheinlich am besten, diese Person einfach in Ihr Zimmer zu rufen, damit sie sehen kann, wonach Sie suchen beim.)
Wenn der Konflikt länger dauert, schneide ich jeden der drei Abschnitte aus und füge ihn in drei separate Dateien ein, z. B. "meine", "gemeinsame" und "ihre".
Dann kann ich die folgenden Befehle ausführen, um die beiden Diff-Hunks zu sehen, die den Konflikt verursacht haben:
diff common mine
diff common theirs
Dies ist nicht dasselbe wie die Verwendung eines Zusammenführungswerkzeugs, da ein Zusammenführungswerkzeug auch alle nicht widersprüchlichen Diff-Hunks enthält. Ich finde das ablenkend.
Jemand hat dies bereits erwähnt, aber das Verständnis der Absicht hinter jedem Diff-Stück ist im Allgemeinen sehr hilfreich, um zu verstehen, woher ein Konflikt kam und wie man damit umgeht.
git log --merge -p <name of file>
Dies zeigt alle Commits, 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 bereits in beiden Zweigen vorhanden sind.) Auf diese Weise können Sie verschiedene Hunks ignorieren, die eindeutig kein Faktor in Ihrem aktuellen Konflikt sind.
Überprüfen Sie Ihre Änderungen mit automatisierten Tools.
Wenn Sie automatisierte Tests haben, führen Sie diese aus. Wenn Sie Flusen haben , führen Sie diese aus. Wenn es sich um ein baubares Projekt handelt, erstellen Sie es vor dem Festschreiben usw. In jedem Fall müssen Sie einige Tests durchführen, um sicherzustellen, dass Ihre Änderungen nichts beschädigen. (Selbst eine Zusammenführung ohne Konflikte kann den Arbeitscode beschädigen.)
Vorausplanen; mit Mitarbeitern kommunizieren.
Wenn Sie vorausplanen und wissen, woran andere arbeiten, können Sie Zusammenführungskonflikte vermeiden und / oder sie früher lösen - solange die Details noch nicht bekannt sind.
Wenn Sie beispielsweise wissen, dass Sie und eine andere Person an unterschiedlichen Refactoring-Vorgängen arbeiten, die sich beide auf denselben Dateisatz auswirken, sollten Sie im Voraus miteinander sprechen und ein besseres Gefühl dafür bekommen, um welche Art von Änderungen es sich bei jedem von Ihnen handelt Herstellung. Sie können viel Zeit und Mühe sparen, wenn Sie Ihre geplanten Änderungen nicht parallel, sondern seriell durchführen.
Bei größeren Refactorings, die sich über einen großen Codebereich erstrecken, sollten Sie unbedingt seriell arbeiten: Jeder hört auf, an diesem Bereich des Codes zu arbeiten, während eine Person das vollständige Refactoring durchführt.
Wenn Sie nicht seriell arbeiten können (möglicherweise aufgrund von Zeitdruck), hilft Ihnen die Kommunikation über erwartete Zusammenführungskonflikte zumindest dabei, die Probleme früher zu lösen, während die Details noch im Auge behalten werden. Wenn ein Mitarbeiter beispielsweise innerhalb eines Zeitraums von einer Woche eine störende Reihe von Commits durchführt, können Sie sich dafür entscheiden, diesen Mitarbeiterzweig in dieser Woche ein- oder zweimal täglich zusammenzuführen / neu zu gründen. Auf diese Weise können Sie Konflikte beim Zusammenführen / Wiederherstellen schneller lösen, als wenn Sie einige Wochen warten, um alles in einem großen Klumpen zusammenzuführen.
Wenn Sie sich bei einer Zusammenführung nicht sicher sind, erzwingen Sie sie nicht.
Das Zusammenführen kann sich überwältigend anfühlen, insbesondere wenn viele widersprüchliche Dateien vorhanden sind und die Konfliktmarkierungen Hunderte von Zeilen abdecken. Oftmals haben wir bei der Schätzung von Softwareprojekten nicht genügend Zeit für Overhead-Elemente wie die Bearbeitung einer knorrigen Zusammenführung. Daher ist es eine echte Belastung, mehrere Stunden damit zu verbringen, jeden Konflikt zu analysieren.
Auf lange Sicht sind vorausschauendes Planen und das Wissen darüber, woran andere arbeiten, die besten Werkzeuge, um Zusammenführungskonflikte zu antizipieren und sich darauf vorzubereiten, sie in kürzerer Zeit korrekt zu lösen.
p4merge
, die separat von den anderen Tools von Perforce installiert und verwendet werden kann (die ich nicht verwendet habe, über die ich jedoch Beschwerden gehört habe).
git config merge.conflictstyle diff3
- Danke mein Herr. Das ist erstaunlich und hat mich von dem Versuch befreit, eine gute 3-Wege-Merge-GUI zu finden (und zu bezahlen). IMO ist dies besser, da es den gemeinsamen Vorfahren sowie lokal / remote und die letzten Festschreibungsprotokollzeilen anzeigt, die (AFAIK) keine GUI ausführt. Die Commits helfen Ihnen definitiv dabei, festzustellen, welcher Code zu welchem Zweig gehört.
Identifizieren Sie, welche Dateien in Konflikt stehen (Git sollte Ihnen dies mitteilen).
Öffnen Sie jede Datei und untersuchen Sie die Unterschiede. Git grenzt sie ab. Hoffentlich ist klar, welche Version jedes Blocks beibehalten werden soll. Möglicherweise müssen Sie dies mit anderen Entwicklern besprechen, die den Code festgeschrieben haben.
Sobald Sie den Konflikt in einer Datei gelöst haben git add the_file
.
Wenn Sie alle Konflikte gelöst haben , führen Sie den git rebase --continue
Befehl aus, den Git nach Abschluss ausgeführt hat.
git add
Dateien im Index bereit ; es ist nicht alles in das Repository hinzufügen. git commit
Fügt Dinge zum Repository hinzu. Diese Verwendung ist für Zusammenführungen sinnvoll. Durch die Zusammenführung werden automatisch alle Änderungen vorgenommen, die automatisch zusammengeführt werden können. Es liegt in Ihrer Verantwortung, den Rest der Änderungen zusammenzuführen und diese dem Index hinzuzufügen, wenn Sie fertig sind.
Schauen Sie sich die Antworten in der Frage zum Stapelüberlauf an. Abbrechen einer Zusammenführung in Git , insbesondere die Antwort von Charles Bailey, die zeigt, wie die verschiedenen Versionen der Datei mit Problemen angezeigt werden, z.
# 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
Zusammenführungskonflikte treten auf, wenn gleichzeitig Änderungen an einer Datei vorgenommen werden. Hier erfahren Sie, wie Sie es lösen können.
git
CLIHier sind einfache Schritte, was zu tun ist, wenn Sie in einen Konfliktzustand geraten:
git status
(unter Unmerged paths
Abschnitt).Lösen Sie die Konflikte für jede Datei separat mit einem der folgenden Ansätze:
Verwenden Sie die GUI, um die Konflikte zu lösen: git mergetool
(der einfachste Weg).
Verwenden Sie zum Akzeptieren einer Remote- / anderen Version : git checkout --theirs path/file
. Dadurch werden alle lokalen Änderungen abgelehnt, die Sie für diese Datei vorgenommen haben.
Verwenden Sie zum Akzeptieren der lokalen / unserer Version: git checkout --ours path/file
Sie müssen jedoch vorsichtig sein, da bei Remote-Änderungen Konflikte aus irgendeinem Grund vorgenommen wurden.
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 <<<<<
/ >>>>>
und wählen Sie die Version entweder von oben oder unten aus =====
. Siehe: Wie Konflikte dargestellt werden .
Pfad- und Dateinamenkonflikte können durch git add
/ gelöst werden git rm
.
Überprüfen Sie abschließend die Dateien, die zum Festschreiben bereit sind, mit : git status
.
Wenn Sie noch Dateien unter Unmerged paths
haben und den Konflikt manuell gelöst haben, teilen Sie Git mit, dass Sie ihn gelöst haben durch : git add path/file
.
Wenn alle Konflikte erfolgreich gelöst wurden, übernehmen Sie die Änderungen mit: git commit -a
und drücken Sie wie gewohnt auf Remote.
Siehe auch: Lösen eines Zusammenführungskonflikts über die Befehlszeile bei GitHub
Ein praktisches Tutorial finden Sie unter: Szenario 5 - Beheben von Zusammenführungskonflikten von Katacoda .
Ich habe DiffMerge erfolgreich verwendet, mit dem Dateien unter Windows, MacOS und Linux / Unix visuell verglichen und zusammengeführt werden können.
Es kann grafisch die Änderungen zwischen 3 Dateien anzeigen und ermöglicht das automatische Zusammenführen (wenn dies sicher ist) und die vollständige Kontrolle über das Bearbeiten der resultierenden Datei.
Bildquelle: DiffMerge (Linux-Screenshot)
Einfach herunterladen und im Repo ausführen als:
git mergetool -t diffmerge .
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 extra 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 "$@"
Dann können Sie die folgenden Tastaturkürzel verwenden:
Alternativ können Sie opendiff (Teil von Xcode Tools) verwenden, mit dem Sie zwei Dateien oder Verzeichnisse zusammenführen können, um eine dritte Datei oder ein drittes Verzeichnis zu erstellen.
Wenn Sie häufig kleine Commits durchführen, lesen Sie zunächst die Commit-Kommentare mit git log --merge
. Dann git diff
zeigen wir Ihnen 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"
Ihre gewählte Werkzeug eingestellt und dann git mergetool
nach einer fehlgeschlagenen Merge finden Sie die Differentiale im Kontext zeigen.
Jedes Mal, wenn Sie eine Datei bearbeiten, um einen Konflikt zu lösen, git add filename
wird der Index aktualisiert und Ihr Diff zeigt ihn nicht mehr an. Wenn alle Konflikte behandelt wurden und ihre Dateien git add
-ed wurden, git commit
wird Ihre Zusammenführung abgeschlossen.
Sehen Sie, wie Konflikte vorgestellt oder in Git, die git merge
Dokumentation zu verstehen , was merge Konfliktmarken sind.
Im Abschnitt So lösen Sie Konflikte wird außerdem erläutert, wie Sie die Konflikte lösen:
Nachdem Sie einen Konflikt gesehen haben, können Sie zwei Dinge tun:
Entscheide dich nicht zusammenzuführen. Die einzige Bereinigung, die Sie benötigen, besteht darin, die Indexdatei auf das
HEAD
Commit zurückzusetzen, um 2. umzukehren, und die durch 2. und 3 vorgenommenen Änderungen am Arbeitsbaum zu bereinigen.;git merge --abort
kann dafür 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 Siegit commit
, um den Deal zu besiegeln.Sie können den Konflikt mit einer Reihe von Tools lösen:
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-Unterschied an, der Änderungen sowohl von derHEAD
als auch von derMERGE_HEAD
Version hervorhebt .Schauen Sie sich die Unterschiede zwischen den einzelnen Zweigen an.
git log --merge -p <path>
zeigt zuerst Unterschiede für dieHEAD
Version und dann dieMERGE_HEAD
Version an.Schauen Sie sich die Originale an.
git show :1:filename
zeigt den gemeinsamen Vorfahren,git show :2:filename
zeigt dieHEAD
Version undgit show :3:filename
zeigt dieMERGE_HEAD
Version.
Weitere Informationen zu Zusammenführungskonfliktmarkierungen und deren Lösung finden Sie im Pro Git -Buchabschnitt Grundlegende Zusammenführungskonflikte .
Ich möchte entweder meine oder ihre Version vollständig oder einzelne Änderungen überprüfen und für jede von ihnen entscheiden.
Akzeptiere meine oder ihre Version voll und ganz :
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 Folgendes ausführen möchten :
git merge --strategy-option ours
oder
git merge --strategy-option theirs
Überprüfen Sie alle Änderungen und akzeptieren Sie sie einzeln
git mergetool
git add <filename>
git commit -m "merged bla bla"
Standard mergetool
funktioniert in der Kommandozeile . Die Verwendung eines Befehlszeilen-Mergetools sollte eine separate Frage sein.
Sie können dazu auch ein visuelles Tool installieren , z. B. meld
ausführen
git mergetool -t meld
Es werden die lokale Version (unsere), die "Basis" - oder "zusammengeführte" Version (das aktuelle Ergebnis der Zusammenführung) und die Remote-Version (ihre) geöffnet. Speichern Sie die zusammengeführte Version, wenn Sie fertig sind, und führen Sie sie git mergetool -t meld
erneut aus, bis "Keine Dateien müssen zusammengeführt werden" angezeigt wird. Fahren Sie dann mit den Schritten 3 und 4 fort.
Für Emacs- Benutzer, die Zusammenführungskonflikte halbmanuell 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 einzeln oder auf einmal, indem Sie:
emacs $(git diff --name-only --diff-filter=U)
Geben Sie beim Aufrufen eines Puffers, der Änderungen in Emacs erfordert, 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ächste Region), 'p' (vorherige Region). Drücken Sie 'a' und 'b', um meine oder ihre Region in den Ausgabepuffer zu kopieren. Und / oder bearbeiten Sie den Ausgabepuffer direkt.
Wenn Sie fertig sind: Drücken Sie 'q'. Emacs fragt Sie, ob Sie diesen Puffer speichern möchten: Ja. Nachdem Sie einen Puffer beendet haben, markieren Sie ihn als gelöst, indem Sie vor dem Verbrecher davonlaufen:
git add FILENAME
Wenn Sie mit allen Puffertypen fertig sind
git commit
um die Zusammenführung zu beenden.
Wenn ich in den obigen Antworten von Pull / Fetch / Merge spreche, möchte ich einen interessanten und produktiven Trick teilen.
git pull --rebase
Dieser obige Befehl ist der nützlichste Befehl in meinem Git-Leben, der viel Zeit gespart hat.
Bevor Sie Ihre neu festgeschriebene Änderung auf den Remote-Server übertragen, versuchen Sie es git pull --rebase
lieber git pull
manuell. Die merge
neuesten Änderungen am Remote-Server werden automatisch synchronisiert (mit einem Abruf + Zusammenführen) und Ihr lokales letztes Festschreiben wird im Git-Protokoll ganz oben platziert. 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
Wenn Sie genau wissen, dass Änderungen in einem der Repositorys nicht wichtig sind und alle Änderungen zugunsten des anderen auflösen möchten, verwenden Sie einfach:
git checkout . --ours
um Änderungen zugunsten Ihres Repositorys aufzulösen , oder
git checkout . --theirs
Änderungen zugunsten des anderen oder des Haupt-Repositorys aufzulösen .
Andernfalls müssen Sie ein GUI-Zusammenführungstool verwenden, um Dateien nacheinander zu durchlaufen, beispielsweise das Zusammenführungstool p4merge
, oder einen Namen zu schreiben, den Sie bereits installiert haben
git mergetool -t p4merge
und nachdem Sie eine Datei fertiggestellt haben, müssen Sie sie speichern und schließen, damit die nächste geöffnet wird.
Führen Sie die folgenden Schritte aus, um Zusammenführungskonflikte in Git zu beheben:
Überprüfen Sie den Git-Status: Git-Status
Holen Sie sich das Patchset: git fetch (checken Sie den richtigen Patch aus Ihrem Git-Commit aus)
Kasse eines lokalen Zweigs (temp1 in meinem Beispiel hier): git checkout -b temp1
Ziehen Sie den letzten Inhalt vom Master: git pull --rebase origin master
Starten Sie das Mergetool und überprüfen Sie die Konflikte und beheben Sie sie ... und überprüfen Sie die Änderungen im Remote-Zweig mit Ihrem aktuellen Zweig: git mergetool
Überprüfen Sie den Status erneut: Git-Status
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 richtige Version Ihrer Dateien hinzu. git add #your_changed_correct_files
Überprüfen Sie den Status erneut: Git-Status
Übernehmen Sie die Änderungen in dieselbe Festschreibungs-ID (dies vermeidet einen neuen separaten Patch-Satz): git commit --amend
Push zum Master-Zweig: Git Push (zu Ihrem Git-Repository)
Es gibt 3 Schritte:
Finden Sie per Befehl heraus, welche Dateien Konflikte verursachen
git status
Überprüfen Sie die Dateien, in denen Sie die als markiert markierten Konflikte finden würden
<<<<<<<<head
blablabla
Ändern Sie es nach Ihren Wünschen und schreiben Sie es dann mit Befehlen fest
git add solved_conflicts_files
git commit -m 'merge msg'
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-Repositorys ablaufen. Der Schlüssel dazu ist das Verständnis von Tracking-Zweigen. Ich habe festgestellt, dass ich den Tracking-Zweig als das "fehlende Teil in der Mitte" zwischen meinem lokalen, tatsächlichen Dateiverzeichnis und der als Ursprung definierten Fernbedienung betrachte.
Ich persönlich habe mir 2 Dinge angewöhnt, um dies zu vermeiden.
Anstatt:
git add .
git commit -m"some msg"
Welches hat zwei Nachteile -
a) Alle neuen / geänderten Dateien werden hinzugefügt und dies kann einige unerwünschte Änderungen beinhalten.
b) Sie können die Dateiliste nicht zuerst überprüfen.
Also mache ich stattdessen:
git add file,file2,file3...
git commit # Then type the files in the editor and save-quit.
Auf diese Weise können Sie besser überlegen, welche Dateien hinzugefügt werden, und Sie können auch die Liste überprüfen und etwas mehr darüber nachdenken, während Sie den Editor für die Nachricht verwenden. Ich finde, dass es auch meine Commit-Nachrichten verbessert, wenn ich einen Vollbild-Editor anstelle des verwende-m
Option verwende.
[Update - mit der Zeit habe ich mehr gewechselt zu:
git status # Make sure I know whats going on
git add .
git commit # Then use the editor
]]
Außerdem (und relevanter für Ihre Situation) versuche ich zu vermeiden:
git pull
oder
git pull origin master.
Da Pull eine Zusammenführung impliziert und Sie lokal Änderungen haben, die Sie nicht zusammenführen möchten, kann dies leicht zu zusammengeführtem Code und / oder Zusammenführungskonflikten für Code fü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.
Dies kann auch hilfreich sein:
Git Branch, Fork, Fetch, Merge, Rebase und Clone, was sind die Unterschiede?
git checkout master
und git fetch
und git rebase --hard origin/master
git add .
werden unsere lokalen Änderungen speichern, damit wir nachverfolgen können git checkout master
? oder sind es zwei verschiedene szenarien?
$ git rebase --hard origin/master b5a30cc159ba8dd error: unknown option
harte Verwendung: Git Rebase [-i] [Optionen] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>] oder: Git Rebase [-i] [ Optionen] [--exec <cmd>] [--onto <newbase>] --root [<branch>] oder: git rebase --continue | --abort | --skip | --edit-todo `
Die Antwort von CoolAJ86 fasst so ziemlich alles zusammen. Wenn Sie Änderungen in beiden Zweigen im selben Code haben, müssen Sie eine manuelle Zusammenführung durchführen. Öffnen Sie die in Konflikt stehende Datei in einem beliebigen Texteditor, und Sie sollten die folgende Struktur sehen.
(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 so aus, wie es der neue Code sein soll, und entfernen Sie dabei Gleichheitszeichen und spitze Klammern.
git commit -a -m "commit message"
git push origin master
git log --merge -p [[--] path]
Scheint nicht immer für mich zu funktionieren und zeigt normalerweise jedes Commit an, das zwischen den beiden Zweigen unterschiedlich war. Dies geschieht sogar bei Verwendung --
der Pfad vom Befehl getrennt wird.
Um dieses Problem zu umgehen, öffne ich zwei Befehlszeilen und in einem Durchgang
git log ..$MERGED_IN_BRANCH --pretty=full -p [path]
und in der anderen
git log $MERGED_IN_BRANCH.. --pretty=full -p [path]
Ersetzen $MERGED_IN_BRANCH
durch den Zweig, den ich zusammengeführt habe, und [path]
durch die Datei, die in Konflikt steht. Dieser Befehl protokolliert alle Commits in Patch-Form zwischen ( ..
) zwei Commits. Wenn Sie eine Seite leer lassen, wie in den obigen Befehlen beschrieben, wird git automatisch verwendet HEAD
(der Zweig, in den Sie in diesem Fall zusammenführen).
Auf diese Weise können Sie sehen, welche Commits in die Datei in den beiden Zweigen eingegangen sind, nachdem sie auseinander gegangen sind. Es macht es normalerweise viel einfacher, Konflikte zu lösen.
patience
Ich bin überrascht, dass sonst niemand über die Lösung von Konflikten patience
mit der rekursiven Zusammenführungsstrategie gesprochen hat. Verwenden Sie für einen großen Zusammenführungskonfliktpatience
lieferte die gute Ergebnisse für mich. Die Idee ist, dass versucht wird, Blöcke und nicht einzelne Zeilen abzugleichen.
Wenn Sie beispielsweise den Einzug Ihres Programms ändern, stimmt die Standardstrategie für das Zusammenführen von Git manchmal mit einzelnen Klammern überein, {
die zu verschiedenen Funktionen gehören. Dies wird vermieden mit patience
:
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.
Wenn Sie einen Zusammenführungskonflikt haben und sehen möchten, was andere beim Ändern ihres Zweigs im Sinn hatten, ist es manchmal einfacher, ihren Zweig direkt mit dem gemeinsamen Vorfahren zu vergleichen (anstelle unseres Zweigs). Dafür können Sie verwenden merge-base
:
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>
Ab dem 12. Dezember 2016 können Sie Zweige auf github.com zusammenführen und Konflikte lösen
Wenn Sie also nicht die Befehlszeile oder Tools von Drittanbietern verwenden möchten, die hier aus älteren Antworten angeboten werden , verwenden Sie das native Tool von GitHub.
In diesem Blog-Beitrag wird dies ausführlich erläutert. Die Grundlagen sind jedoch, 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ührungskonflikte bearbeiten können.
Wenn Sie vom Zweig (Test) zum Master zusammenführen möchten, können Sie die folgenden Schritte ausführen:
Schritt 1 : Gehen Sie zur Filiale
git checkout test
Schritt 2 :
git pull --rebase origin master
Schritt 3 : Wenn es Konflikte gibt, gehen Sie zu diesen Dateien, um sie zu ändern.
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 besteht, fahren Sie erneut mit Schritt 3 fort. Wenn kein Konflikt vorliegt, gehen Sie wie folgt vor:
git push origin +test
Schritt 7 : Und dann gibt es keinen Konflikt zwischen Test und Master. Sie können Merge direkt verwenden.
Ich befolge immer die folgenden Schritte, um Konflikte zu vermeiden.
Jetzt können Sie das Gleiche tun und so viele lokale Filialen pflegen, wie Sie möchten, und gleichzeitig arbeiten, indem Sie bei Bedarf eine Git-Kasse für Ihre Filiale durchführen.
Zusammenführungskonflikte können in verschiedenen Situationen auftreten:
Sie müssen ein Zusammenführungstool installieren, das mit Git kompatibel ist, um die Konflikte zu lösen. Ich persönlich benutze KDiff3 und 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 zum Installieren von Kdiff3.
Richten Sie dann 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 zunächst, die Zusammenführungskonflikte automatisch zu lösen. Die meisten Konflikte würden spontan gelöst und Sie müssen den Rest manuell beheben.
So sieht Kdiff3 aus:
Wenn Sie fertig sind, speichern Sie die Datei und sie wechselt zur nächsten Datei mit Konflikt. Sie tun dasselbe erneut, 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 das folgende Ergebnis erhalten:
$git mergetool
No files need merging
Diese Antwort soll eine Alternative für diejenigen VIM-Benutzer wie mich hinzufügen, die es vorziehen, alles im Editor zu erledigen.
Tpope hat dieses großartige Plugin für VIM namens Fugitive entwickelt . Nach der Installation können Sie :Gstatus
die Dateien mit Konflikten und überprüfen:Gdiff
Git auf drei Arten zusammenführen.
Sobald Sie die 3-Wege-Zusammenführung durchgeführt haben, können Sie mit fugitive die Änderungen aller Zweige, die Sie zusammenführen, auf folgende Weise abrufen:
:diffget //2
, Änderungen vom ursprünglichen Zweig ( HEAD ) abrufen::diffget //3
, Änderungen vom Zusammenführen des Zweigs erhalten: Wenn Sie mit dem Zusammenführen der Datei fertig sind, geben Sie :Gwrite
den zusammengeführten Puffer ein. Vimcasts hat ein großartiges Video veröffentlicht , in dem diese Schritte ausführlich erklärt werden.
Sie können Gitlense für VS Code ausprobieren. Die wichtigsten Funktionen sind:
Diese Funktion gefällt mir bereits:
Und es gibt viele Funktionen, die Sie hier überprüfen können .
git fetch
git checkout deines
git rebase master
In diesem Schritt versuchen Sie, den Konflikt mit Ihrer bevorzugten IDE zu beheben
Sie können diesem Link folgen, um zu überprüfen, ob der Konflikt in der Datei
https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/ behoben werden kann.
git add
git rebase -
git commit fortsetzen -
git push origin ändern HEAD: refs / Drafts / Master (Push wie ein Entwurf)
Jetzt ist alles in Ordnung und Sie werden Ihr Commit in Gerrit finden
Ich hoffe, dass dies jedem in dieser Angelegenheit helfen wird.
Versuchen Sie es mit Visual Studio Code, wenn Sie es noch nicht getan haben. Nachdem Sie versucht haben, zusammenzuführen (und in Zusammenführungskonflikten zu landen), erkennt der VS-Code die Zusammenführungskonflikte automatisch.
Es kann Ihnen sehr gut helfen, indem es zeigt, welche Änderungen am Original vorgenommen wurden und ob Sie incoming
oder akzeptieren sollten
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.
Ein sicherer Weg, um Konflikte zu lösen, ist die Verwendung von git- mediate (die hier vorgeschlagenen gängigen Lösungen sind imho ziemlich fehleranfällig).
In diesem Beitrag finden Sie eine kurze Einführung in die Verwendung.
Für diejenigen, die Visual Studio verwenden (2015 in meinem Fall)
Schließen Sie Ihr Projekt in VS. Besonders in großen Projekten neigt VS dazu, beim Zusammenführen über die Benutzeroberfläche auszuflippen.
Führen Sie die Eingabeaufforderung zum Zusammenführen ein.
git checkout target_branch
git merge source_branch
Öffnen Sie dann das Projekt in VS und gehen Sie zu Team Explorer -> Zweig. Jetzt gibt es eine Nachricht, die besagt, dass die Zusammenführung aussteht und widersprüchliche Dateien direkt unter der Nachricht aufgelistet sind.
Klicken Sie auf die widersprüchliche Datei, und Sie haben die Möglichkeit, zusammenzuführen, zu vergleichen, Quelle zu übernehmen und Ziel zu übernehmen. Das Zusammenführungswerkzeug in VS ist sehr einfach zu verwenden.
Wenn Sie IntelliJ als IDE verwenden Versuchen Sie, das übergeordnete Element mit Ihrem Zweig zusammenzuführen
git checkout <localbranch>
git merge origin/<remotebranch>
Es werden alle Konflikte wie diese angezeigt
A_MBPro: test anu $ git merge origin / Automatisches Zusammenführen von src / test / java / com /.../ TestClass.java CONFLICT (Inhalt): Zusammenführungskonflikt in src / test / java / com /.../ TestClass.java
Beachten Sie nun, dass die Datei TestClass.java in IntelliJ rot angezeigt wird. Außerdem wird der Git-Status 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 ändert sich HEAD in Ihrem lokalen Zweig und Ursprung / ist Änderungen in der Remote-Niederlassung. Bewahren Sie hier das benötigte Material auf und entfernen Sie das nicht benötigte Material. Danach sollten die normalen Schritte ausgeführt werden. Das ist
git add TestClass.java
git commit -m "commit message"
git push
Ich verwende den visuellen Code von Microsoft zur Lösung von Konflikten. Es ist sehr einfach zu bedienen. Ich halte mein Projekt im Arbeitsbereich offen. Es erkennt und hebt Konflikte hervor und bietet darüber hinaus GUI-Optionen zur Auswahl der Änderungen, die ich von HEAD oder eingehend fernhalten möchte.