Ich bin in einen Zusammenführungskonflikt geraten. Wie kann ich die Zusammenführung abbrechen?

2539

Ich git pullhabe einen Zusammenführungskonflikt verwendet und hatte:

unmerged:   _widget.html.erb

You are in the middle of a conflicted merge.

Ich weiß, dass die andere Version der Datei gut und meine schlecht ist, daher sollten alle meine Änderungen aufgegeben werden. Wie kann ich das machen?

Gwyn Morfey
quelle
30
Mir ist klar, dass dies eine sehr alte Frage ist, aber möchten Sie die gesamte Zusammenführung abbrechen und den Zweig, den Sie zusammengeführt haben, nicht zusammenführen, oder diese eine Datei einfach als Teil einer größeren Zusammenführung ignorieren und alle anderen Dateien als zusammenführen lassen normal? Für mich impliziert Ihr Titel das erstere, Ihr Fragetext will das letztere. Die Antworten machen beides, ohne die Dinge klar zu machen.
rjmunro
Ich habe einen ähnlichen Fall beim Festschreiben erhalten, der besagt, dass die automatische Zusammenführung fehlgeschlagen ist. Beheben Sie Konflikte und legen Sie das Ergebnis fest:[rejected] gh-pages -> gh-pages (non-fast-forward)
Chetabahana
4
Gwyn, es könnte nützlich sein, hier eine akzeptierte Antwort auszuwählen. Die am besten gewählte ist etwas weniger sicher als einige der aktuelleren Lösungen, daher denke ich, dass es hilfreich wäre, andere darüber hervorzuheben :)
Amicable

Antworten:

2220

Da Sie nicht pullerfolgreich waren, ist HEAD(nicht HEAD^) das letzte "gültige" Commit in Ihrem Zweig:

git reset --hard HEAD

Das andere Stück, das Sie möchten, ist, dass ihre Änderungen Ihre Änderungen überschreiben.

In älteren Versionen von git konnten Sie die Zusammenführungsstrategie "ihrer" verwenden:

git pull --strategy=theirs remote_branch

Dies wurde jedoch inzwischen entfernt, wie in dieser Nachricht von Junio ​​Hamano (dem Git-Betreuer) erläutert . Wie im Link angegeben , würden Sie stattdessen Folgendes tun:

git fetch origin
git reset --hard origin
Pat Notz
quelle
49
Anstatt einen Hard-Reset durchzuführen, können Sie ihn auf eine detailliertere Ebene bringen, indem Sie Folgendes tun: git fetch origin -> git reset origin (soft reset, your changes are still present) -> git checkout file_to_use_their_version_of another_file (steamroll your own changes back to match the origin) Ich verwende Git Pull nie mehr. Da in einem Kampf zwischen meinem neuesten Code und dem Ursprung der Ursprung immer gewinnen sollte, habe ich immer git fetchund git rebase origin. Dies macht meine Verschmelzungen und Konflikte tatsächlich selten.
Kzqai
7
Genau. Ich hole auch gerne zuerst ab und untersuche dann die Upstream-Änderungen ( git log ..@{upstream}oder git diff ..@{upstream}). Danach werde ich wie Sie meine Arbeit neu begründen.
Pat Notz
162
Wie in einer neueren Antwort erwähnt, ist es ab Version 1.6.1 möglich, 'git reset --merge'
Matt Ball am
5
Früher habe ich git merge -X theirs remote_branchstatt git pull --strategy=theirs remote_branchwie theirssieht aus wie eine Optionrecursive
mlt
14
git merge --abortist weit vorzuziehen.
Daniel Cassidy
1956

Wenn Ihre Git-Version> = 1.6.1 ist, können Sie verwenden git reset --merge.

Wie @Michael Johnson erwähnt, können Sie auch verwenden, wenn Ihre Git-Version> = 1.7.4 ist git merge --abort.

Stellen Sie wie immer sicher, dass Sie keine nicht festgeschriebenen Änderungen vorgenommen haben, bevor Sie mit dem Zusammenführen beginnen.

Auf der Manpage zum Zusammenführen von Git

git merge --abortist äquivalent zu git reset --mergewann MERGE_HEADvorhanden ist.

MERGE_HEAD ist vorhanden, wenn eine Zusammenführung ausgeführt wird.

Auch in Bezug auf nicht festgeschriebene Änderungen beim Starten einer Zusammenführung:

Wenn Sie Änderungen haben, die Sie vor dem Starten einer Zusammenführung nicht festschreiben möchten, sondern nur git stashvor der Zusammenführung und git stash popnach Abschluss der Zusammenführung oder nach dem Abbrechen.

Carl
quelle
3
Interessant - aber das Handbuch macht mir Angst. Wann genau ist es angebracht zu verwenden? Wann müssten Sie das optionale angeben <commit>? #GitMoment: -o
conny
1
Normalerweise verwenden Sie diese Option, wenn Sie die Zusammenführung von Anfang an wiederholen möchten. Ich musste das optionale Commit nie selbst angeben, daher ist der Standardwert (kein optionales <commit>) in Ordnung.
Carl
44
Ich wünschte, diese Antwort hätte mehr Stimmen! An diesem Punkt scheint es in vielen Fällen die relevanteste Lösung zu sein.
Jay Taylor
1
Selbst mit nicht festgeschriebenen Änderungen konnte git den Status vor dem Zusammenführen wiederherstellen. Nett!
T3rm1
2
Ist git merge --abortnur ein Synonym für git reset --merge? Der Name ist sicherlich sinnvoller, aber hat er die gleiche Funktionalität?
Tikhon Jelvis
518
git merge --abort

Brechen Sie den aktuellen Konfliktlösungsprozess ab und versuchen Sie, den Status vor dem Zusammenführen zu rekonstruieren.

Wenn zu Beginn der Zusammenführung nicht festgeschriebene Änderungen am Arbeitsbaum vorhanden waren, git merge --abortkönnen diese Änderungen in einigen Fällen nicht rekonstruiert werden. Es wird daher empfohlen, Ihre Änderungen immer festzuschreiben oder zu speichern, bevor Sie git merge ausführen.

git merge --abortist äquivalent zu git reset --mergewann MERGE_HEADvorhanden ist.

http://www.git-scm.com/docs/git-merge

ignis
quelle
16
Dies ist seit Git v1.7.4 verfügbar. Es ist ein Alias ​​für git reset --merge.
Michael Johnson
162

Es ist so einfach.

git merge --abort

Git selbst zeigt Ihnen die Lösung, wenn Sie in solchen Schwierigkeiten sind, und führt den Befehl git status aus.

git status

Hoffe das wird den Menschen helfen.

Jagruttam Panchal
quelle
97

Ich denke, git resetdu brauchst es.

Beachten Sie, dass git revertdies etwas ganz anderes bedeutet als beispielsweise svn revert: In Subversion verwirft das Zurücksetzen Ihre (nicht festgeschriebenen) Änderungen und gibt die Datei aus dem Repository auf die aktuelle Version zurück, während git revertein Commit "rückgängig gemacht" wird.

git resetsollte das Äquivalent tun svn revert, dh Ihre unerwünschten Änderungen verwerfen.

David Precious
quelle
76

In diesem speziellen Anwendungsfall möchten Sie die Zusammenführung nicht wirklich abbrechen, sondern den Konflikt nur auf eine bestimmte Weise lösen.

Es ist auch nicht besonders erforderlich, eine Zusammenführung mit einer anderen Strategie zurückzusetzen und durchzuführen. Die Konflikte wurden von git korrekt hervorgehoben und die Anforderung, die Änderungen der anderen Seiten zu akzeptieren, gilt nur für diese eine Datei.

Für eine nicht zusammengeführte Datei in einem Konflikt stellt git die allgemeinen Basis-, lokalen und Remote-Versionen der Datei im Index zur Verfügung. (Hier werden sie zur Verwendung in einem 3-Wege-Diff-Tool von gelesen git mergetool.) Sie können sie git showzum Anzeigen verwenden.

# common base:
git show :1:_widget.html.erb

# 'ours'
git show :2:_widget.html.erb

# 'theirs'
git show :3:_widget.html.erb

Der einfachste Weg, den Konflikt zu lösen, um die Remote-Version wörtlich zu verwenden, ist:

git show :3:_widget.html.erb >_widget.html.erb
git add _widget.html.erb

Oder mit git> = 1.6.1:

git checkout --theirs _widget.html.erb
CB Bailey
quelle
5
danke für den Tipp. Ist das nicht ein Hauch einer schlechten Git-Benutzeroberfläche?
Peter
@ Peter: Ich bin nicht überzeugt. Das gewünschte Ergebnis ist mit wenigen Grundbefehlen mit einfachen Optionen erreichbar. Welche Verbesserungen würden Sie vorschlagen?
CB Bailey
10
Ich denke, der git 1.6.1Befehl macht sehr viel Sinn und ist gut. Genau das hätte ich mir gewünscht. Ich denke, die Lösung vor 1.6.1 ist unelegant und erfordert Kenntnisse über andere Teile von Git, die vom Prozess der Auflösung von Zusammenführungen getrennt werden sollten. Aber die neue Version ist großartig!
Peter
67

Für ein Szenario wie das habe ich git fetchund git pulldann festgestellt, dass der Upstream-Zweig kein Hauptzweig ist, was zu unerwünschten Konflikten führte.

git reset --merge 

Dies wurde zurückgesetzt, ohne meine lokalen Änderungen zurückzusetzen.

naamadheya
quelle
45

Kommentare deuten darauf hin, dass dies git reset --mergeein Alias ​​für ist git merge --abort. Es ist erwähnenswert, dass dies git merge --abortnur gleichbedeutend ist, git reset --mergewenn a MERGE_HEADvorhanden ist. Dies kann in der Git-Hilfe zum Zusammenführen gelesen werden.

git merge --abort entspricht git reset --merge, wenn MERGE_HEAD vorhanden ist.

Nach einer fehlgeschlagenen Zusammenführung, wenn es keine gibt MERGE_HEAD die fehlgeschlagene Zusammenführung rückgängig gemacht werden git reset --merge, jedoch nicht unbedingt mit git merge --abort. Sie sind nicht nur alte und neue Syntax für dasselbe .

Persönlich finde ich git reset --mergefür Szenarien, die den beschriebenen ähnlich sind, und für fehlgeschlagene Zusammenführungen im Allgemeinen viel leistungsfähiger.

Martin G.
quelle
2
Was ist hier eigentlich mit "fehlgeschlagene Zusammenführung" gemeint? Mit Konflikten oder etwas anderem verschmelzen? Oder um es neu zu formulieren: Wann ist MERGE_HEAD nicht vorhanden? Meine Folgefrage ist da, um die bessere Verwendung von "git reset --merge" besser zu verstehen.
Ewoks
@Ewoks git stash applyverursachte einen Zusammenführungskonflikt für mich, git merge --aborthalf aber nicht, während ich es git reset --mergetat.
Nitzel
27

Wenn Sie einen Zusammenführungskonflikt haben und nichts festschreiben müssen, wird dennoch ein Zusammenführungsfehler angezeigt. Nachdem Sie alle unten genannten Befehle angewendet haben,

git reset --hard HEAD
git pull --strategy=theirs remote_branch
git fetch origin
git reset --hard origin

Bitte entfernen

.git \ index.lock

Datei [Ausschneiden und Einfügen an einer anderen Stelle im Falle einer Wiederherstellung] und geben Sie dann einen der folgenden Befehle ein, je nachdem, welche Version Sie möchten.

git reset --hard HEAD
git reset --hard origin

Ich hoffe, das hilft!!!

Nirav Mehta
quelle
19

Eine Alternative, die den Status der Arbeitskopie beibehält, ist:

git stash
git merge --abort
git stash pop

Ich rate generell davon ab, da es effektiv wie das Zusammenführen in Subversion ist, da es die Verzweigungsbeziehungen im folgenden Commit wegwirft.

Alain O'Dea
quelle
Ich fand diesen Ansatz nützlich, als ich versehentlich zu einem git-svn-Zweig verschmolzen bin, der das nicht gut handhabt. Squash Merges oder Cherry Picks sind besser, wenn Sie mit Git-SVN-Tracking-Zweigen arbeiten. Tatsächlich verwandelt meine Lösung eine Zusammenführung nachträglich in eine Squash-Zusammenführung.
Alain O'Dea
Beste Antwort auf die Frage
Fouad Boukredine
18

Seit Git 1.6.1.3 git checkoutvon beiden Seiten einer Zusammenführung auschecken konnte:

git checkout --theirs _widget.html.erb
Alain O'Dea
quelle
3

Ich habe festgestellt, dass Folgendes für mich funktioniert (eine einzelne Datei in den Status vor dem Zusammenführen zurücksetzen):

git reset *currentBranchIntoWhichYouMerged* -- *fileToBeReset*
Malcolm Boekhoff
quelle
-5

Sourcetree

Da Sie Ihre Zusammenführung nicht festschreiben, doppelklicken Sie einfach auf einen anderen Zweig (was bedeutet, dass Sie ihn auschecken müssen), und wenn Sourcetree Sie nach dem Verwerfen aller Änderungen fragt, stimmen Sie zu :)

Kamil Kiełczewski
quelle