Gibt es eine gute Möglichkeit, zu erklären, wie Zusammenführungskonflikte in Git gelöst werden können?
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.
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!
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:
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.
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.
Ü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.)
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.
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.
Identifizieren Sie, welche Dateien in Konflikt sind (Git sollte Ihnen dies mitteilen).
Ö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.
Sobald Sie den Konflikt in einer Datei git add the_file
gelöst haben.
Sobald Sie all - Konflikte gelöst haben, führen Sie git rebase --continue
oder einen beliebigen anderen Befehl aus.
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
Zusammenführungskonflikte treten auf, wenn gleichzeitig Änderungen an einer Datei vorgenommen werden. Hier erfahren Sie, wie Sie das Problem lösen können.
git
CLIHier sind einfache Schritte, was zu tun ist, wenn Sie in einen Konfliktzustand geraten:
git status
(im Abschnitt Unmerged paths
).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.
Ü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
.
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
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.
Bildquelle: DiffMerge (Linux-Screenshot)
Einfach herunterladen und in 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 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:
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.
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.
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 kanngit 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 Siegit 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 VersionenHEAD
undMERGE_HEAD
hervorhebt.Schauen Sie sich die Unterschiede von jedem Zweig an.
git log --merge -p <path>
zeigt zuerst die 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.
Informationen zum Zusammenführen von Konfliktmarken und deren Behebung finden Sie im Abschnitt Pro Git book Basic Merge Conflicts .
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.
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
git mergetool
git add <filename>
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.
Bitte befolgen Sie die folgenden Schritte, um Zusammenführungskonflikte in Git zu beheben:
Überprüfen Sie den Git-Status: Git-Status
Holen Sie sich das Patchset: git fetch (überprüfen Sie den richtigen Patch von Ihrem Git-Commit)
Checke einen lokalen Zweig aus (temp1 in meinem Beispiel hier): git checkout -b temp1
Ziehen Sie die letzten Inhalte vom Master: git pull --rebase Origin master
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
Überprüfen Sie den Status erneut: git status
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
Überprüfen Sie den Status erneut: git status
Übernehmen Sie die Änderungen in dieselbe Festschreibungs-ID (dies vermeidet ein neues separates Patch-Set): git commit --amend
Push to the master branch: git Push (in dein Git-Repository)
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.
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
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?
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
Es gibt 3 Schritte:
Finden Sie heraus, welche Dateien Konflikte verursachen
git status
Überprüfen Sie die Dateien, in denen Sie die Konflikte wie markiert finden würden
<<<<<<<<head
blablabla
Ä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'
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.
patience
verwendenIch 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.
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>
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.
Ich folge den folgenden Schritten, um Konflikte zu vermeiden.
Jetzt können Sie dasselbe tun und so viele lokale Filialen pflegen, wie Sie möchten, und gleichzeitig arbeiten.
Zusammenführungskonflikte können in verschiedenen Situationen auftreten:
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:
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
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.
Mit diesen Antworten wird eine Alternative für Benutzer von VIM hinzugefügt, wie z. B. ich, die alles im Editor erledigen möchte.
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.
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.
Ich folge dem untenstehenden Prozess.
Der Prozess zum Beheben von Zusammenführungskonflikten:
Ziehen Sie zuerst das neueste aus dem Zielzweig ab, zu dem Sie den git pull Origin develop
einfügen möchten.
Wenn Sie das neueste vom Ziel erhalten, lösen Sie den Konflikt nun manuell in IDE, indem Sie diese zusätzlichen Zeichen löschen.
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.
Führen Sie nach Abschluss von git add
einen git commit
aus, um die Änderungen zu bestätigen.
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.
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
Für diejenigen, die Visual Studio verwenden (2015 in meinem Fall)
Schließen Sie Ihr Projekt in VS. Insbesondere in großen Projekten neigt VS dazu, beim Zusammenführen mit der Benutzeroberfläche auszuflippen.
Führen Sie die Zusammenführung in der Eingabeaufforderung aus.
git checkout target_branch
git merge source_branch
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.
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.
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.
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
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.
Ich habe Beyond Compare installiert. Wenn Sie git mergetool
verwenden, wird BC gestartet.