Ich möchte Zusammenführungskonflikte in meinem Git-Repository auflösen.
Wie kann ich das tun?
Ich möchte Zusammenführungskonflikte in meinem Git-Repository auflösen.
Wie kann ich das tun?
Versuchen Sie es: git mergetool
Es öffnet eine grafische Benutzeroberfläche, die Sie durch die einzelnen Konflikte führt, und Sie können wählen, wie sie zusammengeführt werden sollen. Manchmal muss man danach noch etwas von Hand nachbearbeiten, aber in der Regel reicht das schon aus. Es ist auf jeden Fall viel besser als die ganze Sache von Hand zu machen.
Gemäß Josh Glover's Kommentar :
Der Befehl
öffnet nicht unbedingt eine grafische Benutzeroberfläche, es sei denn, Sie installieren eine. Ausführen von
git mergetool
ergab sich für michvimdiff
verwendet werden. Sie können eines der folgenden Tools installieren, um es stattdessen zu verwenden:meld
,opendiff
,kdiff3
,tkdiff
,xxdiff
,tortoisemerge
,gvimdiff
,diffuse
,ecmerge
,p4merge
,araxis
,vimdiff
,emerge
.
Nachfolgend finden Sie ein Beispiel für ein Verfahren, das Sie verwenden können vimdiff
um Zusammenführungskonflikte zu lösen. Basierend auf dieser 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 Standard-Zusammenführungswerkzeug festgelegt.
Schritt 2 : Führen Sie folgenden Befehl im Terminal aus
git mergetool
Schritt 3 : Sie werden eine vimdiff-Anzeige im folgenden Format sehen
LOCAL BASE REMOTE
MERGED
Diese 4 Ansichten sind
LOCAL - dies ist eine Datei aus dem aktuellen Zweig
BASE - gemeinsamer Vorgänger, wie die Datei vor beiden Änderungen aussah
REMOTE - Datei, die Sie in Ihren Zweig einbinden
MERGED - Ergebnis der Zusammenführung, dies wird im Repo gespeichert
Sie können zwischen diesen Ansichten navigieren, indem Sie ctrl + w . Sie können die MERGED-Ansicht direkt über ctrl + w gefolgt von j .
Weitere Informationen über die vimdiff-Navigation sind aquí et aquí .
Schritt 4 . Sie können die MERGED-Ansicht auf folgende Weise 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 Aufräumen
:wqa
Speichern und Beenden von vi
git commit -m "message"
git clean
Entfernen Sie zusätzliche Dateien (z.B. *.orig), die vom Diff-Tool erstellt wurden.
Zu Ihrer Information: Sie können verwenden git mergetool -y
um ein paar Tastenanschläge zu sparen, wenn Sie viele Dateien auf einmal zusammenführen.
Nun, es wird nicht unbedingt eine grafische Benutzeroberfläche geöffnet, es sei denn, Sie installieren eine. Ausführen von git mergetool
ergab sich für mich vimdiff
verwendet werden. Sie können eines der folgenden Tools installieren, um es stattdessen zu verwenden: meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse ecmerge p4merge araxis vimdiff emerge
.
Gutes Argument, Josh. Auf Ubuntu hatte ich das beste Glück mit meld, seine Drei-Wege-Merge-Anzeige ist nicht schlecht. Auf OSX wählte Git einen schönen Standard.
Hier ist ein wahrscheinlicher Anwendungsfall, von oben:
Sie werden einige Änderungen vornehmen, aber ups, Sie sind nicht auf dem neuesten Stand:
git fetch origin
git pull origin master
From ssh://gitosis@example.com:22/projectname
* branch master -> FETCH_HEAD
Updating a030c3a..ee25213
error: Entry 'filename.c' not uptodate. Cannot merge.
Sie werden also auf den neuesten Stand gebracht 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.
Also beschließen Sie, sich die Änderungen anzusehen:
git mergetool
Oh je, oh je, im Vorfeld wurden einige Dinge geändert, aber nur um meine Änderungen zu verwenden...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 ein letztes Mal
git pull origin master
From ssh://gitosis@example.com:22/projectname
* branch master -> FETCH_HEAD
Already up-to-date.
Ta-da!
Das war sehr hilfreich, denn ich hatte viele Fehler bei der Zusammenführung von Binärdateien (Art-Assets) und die Zusammenführung scheint immer zu scheitern, also muss ich sie immer mit der neuen Datei überschreiben und nicht "zusammenführen".
Das war genau das, wonach ich gesucht habe! Warum, oh warum, kann "git checkout -- filename.c" nicht auch hier funktionieren Das wäre zu konsequent, denke ich.
Vorsichtig! Die Bedeutung von --ours und --theirs ist umgekehrt. --ours == die Ferne. --theirs == das Lokale. Siehe git merge --help
Ich finde, dass mir Merge-Tools selten helfen, den Konflikt oder die Lösung zu verstehen. Normalerweise bin ich erfolgreicher, wenn ich mir die Konfliktmarkierungen in einem Texteditor ansehe und das Git-Protokoll als Ergänzung verwende.
Hier sind ein paar Tipps:
Ich habe festgestellt, dass es am besten ist, den Stil "diff3" für Zusammenführungskonflikte zu verwenden:
git config merge.conflictstyle diff3
Dies führt zu solchen Konfliktmarkierungen:
<<<<<<<
Changes made on the branch that is being merged into. In most cases,
this is the branch that I have currently checked out (i.e. HEAD).
|||||||
The common ancestor version.
=======
Changes made on the branch that is being merged in. This is often a
feature/topic branch.
>>>>>>>
Der mittlere Abschnitt zeigt, wie der gemeinsame Vorfahre aussah. Dies ist nützlich, weil Sie ihn mit der oberen und unteren Version vergleichen können, um ein besseres Gefühl dafür zu bekommen, was auf jedem Zweig geändert wurde, was Ihnen eine bessere Vorstellung davon vermittelt, was der Zweck jeder Änderung war.
Handelt es sich um einen Konflikt, der nur wenige Zeilen umfasst, wird der Konflikt dadurch in der Regel sehr deutlich. (Zu wissen, wie man einen Konflikt löst, ist etwas ganz anderes; man muss wissen, woran andere Leute arbeiten. Wenn Sie verwirrt sind, ist es wahrscheinlich am besten, die betreffende Person in Ihr Zimmer zu rufen, damit sie sehen kann, was Sie gerade sehen.)
Wenn der Konflikt länger ist, 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 einschließt. Das empfinde ich als störend.
Jemand hat es bereits erwähnt, aber die Intention hinter jedem Unterschied zu verstehen, ist im Allgemeinen sehr hilfreich, um zu verstehen, woher ein Konflikt kommt und wie man damit umgehen kann.
git log --merge -p <name of file>
Dies zeigt alle Commits an, die diese Datei zwischen dem gemeinsamen Vorgänger und den beiden Köpfen, die Sie zusammenführen, berührt haben. (Es schließt also keine Commits ein, die bereits vor dem Zusammenführen in beiden Zweigen vorhanden waren.) Dies hilft Ihnen, Diff Hunks zu 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 durch. Wenn Sie eine Fussel , führen Sie das aus. Wenn es sich um ein kompilierbares Projekt handelt, bauen Sie es, bevor Sie es übertragen, usw. In allen Fällen müssen Sie ein paar Tests durchführen, um sicherzustellen, dass Ihre Änderungen nichts kaputt machen. (Sogar ein Merge ohne Konflikte kann funktionierenden Code zerstören).
Planen Sie im Voraus; kommunizieren Sie mit Ihren Mitarbeitern.
Wenn Sie im Voraus planen und wissen, woran andere arbeiten, können Sie Konflikte vermeiden und/oder früher lösen - solange die Details noch frisch im Gedächtnis sind.
Wenn Sie z.B. wissen, dass Sie und eine andere Person an verschiedenen Refactoring-Projekten arbeiten, die beide dieselben Dateien betreffen, sollten Sie vorher miteinander sprechen, um ein besseres Gefühl dafür zu bekommen, welche Art von Änderungen jeder von Ihnen vornimmt. Sie können viel Zeit und Mühe sparen, wenn Sie Ihre geplanten Änderungen nacheinander und nicht parallel durchführen.
Bei größeren Refactorings, die einen großen Teil des Codes betreffen, sollten Sie unbedingt in Erwägung ziehen, seriell zu arbeiten: Jeder stellt die Arbeit an diesem Bereich des Codes ein, während eine Person das komplette Refactoring durchführt.
Wenn Sie nicht seriell arbeiten können (z. B. aufgrund von Zeitdruck), dann hilft Ihnen die Kommunikation über zu erwartende Konflikte bei der Zusammenführung zumindest, die Probleme früher zu lösen, solange die Details noch frisch im Gedächtnis sind. Wenn zum Beispiel ein Kollege eine störende Reihe von Übertragungen über einen Zeitraum von einer Woche macht, können Sie sich dafür entscheiden, den Zweig dieses Kollegen ein- oder zweimal pro Tag während dieser Woche zusammenzuführen/zu rebasen. Auf diese Weise können Sie, wenn Sie Merge/Rebase Konflikte finden, diese schneller lösen, als wenn Sie ein paar Wochen warten, um alles in einem großen Klumpen zusammenzuführen.
Wenn Sie sich bei einer Verschmelzung unsicher sind, sollten Sie sie nicht erzwingen.
Das Zusammenführen von Dateien kann sich sehr anstrengend anfühlen, vor allem, wenn es viele widersprüchliche Dateien gibt und die Konfliktmarkierungen Hunderte von Zeilen umfassen. Bei der Kalkulation von Software-Projekten wird oft nicht genügend Zeit für Overhead-Elemente wie die Bearbeitung eines komplizierten Mergers eingeplant, so dass es sich wie eine echte Qual anfühlt, mehrere Stunden mit dem Sezieren jedes Konflikts zu verbringen.
Langfristig gesehen sind eine vorausschauende Planung und die Kenntnis dessen, woran andere arbeiten, die besten Mittel, um sich auf entstehende Konflikte einzustellen und sich darauf vorzubereiten, sie in kürzerer Zeit korrekt zu lösen.
Die Option diff3 ist eine großartige Funktion für Zusammenführungen. Die einzige GUI, die mir begegnet ist, die sie anzeigt, ist die von Perforce p4merge
das separat von den anderen Perforce-Tools installiert und verwendet werden kann (die ich nicht benutzt habe, über die ich aber Beschwerden gehört habe).
Nach einem Rebase-Versuch, der zu einem Merge-Konflikt führte: $ git log --merge -p build.xml output: fatal: --merge without MERGE_HEAD?
git config merge.conflictstyle diff3
- Ich danke Ihnen, Sir. Dies ist erstaunlich und hat mich von dem Versuch befreit, eine gute 3-Wege-Zusammenführungs-GUI zu finden (und $$ zu bezahlen). IMO ist dies besser, weil es den gemeinsamen Vorfahren sowie lokal/entfernt zeigt, y zeigt die letzten Commit-Log-Zeilen an, was (AFAIK) keine GUI kann. Die Commits helfen Ihnen auf jeden Fall zu erkennen, welcher Code zu welchem Zweig gehört.
Stellen Sie fest, welche Dateien in Konflikt stehen (Git sollte Ihnen das sagen).
Öffnen Sie jede Datei und prüfen Sie die Diffs; Git grenzt sie ab. Hoffentlich ist es offensichtlich, welche Version eines jeden Blocks Sie behalten sollten. Möglicherweise müssen Sie dies mit anderen Entwicklern besprechen, die den Code übertragen haben.
Sobald Sie den Konflikt in einer Datei aufgelöst haben git add the_file
.
Sobald Sie eine Lösung gefunden haben todo Konflikte, tun git rebase --continue
oder welcher Befehl auch immer Git sagte, was Sie tun sollten, als Sie fertig waren.
@Justin Betrachten Sie Git als Tracking Inhalt anstatt Dateien zu verfolgen. Dann ist es einfach zu sehen, dass der Inhalt, den Sie aktualisiert haben ist nicht im Repository und muss hinzugefügt werden. Diese Denkweise erklärt auch, warum Git leere Ordner nicht verfolgt: Obwohl es sich technisch gesehen um Dateien handelt, gibt es keinen Inhalt zu verfolgen.
Inhalt vorhanden ist, tritt ein Konflikt auf, weil es 2 Versionen des Inhalts gibt. Daher klingt "git add" nicht korrekt. Und es funktioniert nicht (git add, git commit), wenn Sie nur diese eine Datei übertragen wollen, nachdem der Konflikt gelöst wurde ("fatal: cannot do a partial commit during a merge.")
Ja, technisch gesehen ist dies eine Antwort auf die gestellte Frage, aber meiner Meinung nach keine brauchbare Antwort, sorry. Was ist die Punkt einen Zweig mit einem anderen gleichzusetzen? Natürlich wird eine Zusammenführung Konflikte verursachen
Zusammenführungskonflikte entstehen, wenn an einer Datei gleichzeitig Änderungen vorgenommen werden. Hier ist, wie man sie löst.
git
CLIHier sind einfache Schritte, was zu tun ist, wenn man in einen Konflikt gerät:
Beachten Sie die Liste der konfliktbehafteten Dateien mit: git status
(unter Unmerged paths
Abschnitt).
Lösen Sie die Konflikte separat für jede Datei auf eine der folgenden Arten:
Verwenden Sie GUI, um die Konflikte zu lösen: git mergetool
(der einfachste Weg).
Um eine entfernte/andere Version zu akzeptieren, verwenden Sie: git checkout --theirs path/file
. Dadurch werden alle lokalen Änderungen, die Sie für diese Datei vorgenommen haben, verworfen.
Um die lokale/unsere Version zu akzeptieren, verwenden Sie: git checkout --ours path/file
Sie müssen jedoch vorsichtig sein, da aus irgendeinem Grund entfernte Änderungen vorgenommen wurden, die Konflikte verursachen.
Verwandt: Was ist die genaue Bedeutung von "unser" und "ihr" in Git?
Bearbeiten Sie die konfliktbehafteten Dateien manuell und suchen Sie den Codeblock zwischen <<<<<
/ >>>>>
dann wählen Sie die Version entweder von oben oder von unten =====
. Siehe: Wie Konflikte dargestellt werden .
Pfad- und Dateinamenkonflikte können gelöst werden durch git add
/ git rm
.
Überprüfen Sie schließlich die Dateien, die für die Übergabe bereit sind: git status
.
Wenn Sie noch Dateien unter Unmerged paths
und Sie den Konflikt manuell gelöst haben, dann lassen Sie Git wissen, dass Sie ihn gelöst haben, indem Sie: git add path/file
.
Wenn alle Konflikte erfolgreich gelöst wurden, übertragen Sie die Änderungen durch: git commit -a
und drücken Sie wie gewohnt auf die Fernbedienung.
Siehe auch: Auflösen eines Zusammenführungskonflikts über die Befehlszeile auf GitHub
Eine praktische Anleitung finden Sie hier: Szenario 5 - Behebung von Konflikten bei der Zusammenführung durch Katacoda .
Ich habe erfolgreich eingesetzt DiffMerge 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 es sicher ist) und die volle Kontrolle über die Bearbeitung der resultierenden Datei.
Bildquelle: DiffMerge (Linux-Bildschirmausschnitt)
Laden Sie es einfach herunter und führen Sie es im Repo als aus:
git mergetool -t diffmerge .
Unter macOS können Sie über installieren:
brew install caskroom/cask/brew-cask
brew cask install diffmerge
Und wahrscheinlich (falls nicht vorhanden) müssen Sie den folgenden einfachen Wrapper in Ihrem PATH platzieren (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 Tastenkombinationen verwenden:
Alternativ können Sie auch opendiff (Teil der Xcode Tools), mit dem Sie zwei Dateien oder Verzeichnisse zusammenführen können, um eine dritte Datei oder ein drittes Verzeichnis zu erstellen.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
40 Stimmen
Der folgende Blog-Beitrag enthält ein sehr gutes Beispiel für den Umgang mit Merge-Konflikten mit Git, das Sie auf den richtigen Weg bringen sollte. Umgang mit und Vermeidung von Konflikten in Git
4 Stimmen
Sie können ein Zusammenführungswerkzeug konfigurieren (kdiff3 jebaird.com/2013/07/08/… ) und verwenden Sie dann git mergetool. Wenn Sie in großen Entwicklerteams arbeiten, werden Sie immer wieder auf Merge-Konflikte stoßen.
0 Stimmen
Vergessen Sie nicht, dass Sie die meisten Merge-Konflikte durch regelmäßiges Merging Downstream entschärfen können!
3 Stimmen
Siehe auch git-tower.com/learn/git/ebook/command-line/tools-services/
0 Stimmen
Dies scheint eine detaillierte Anleitung zu sein - githubtraining.com/fix-merge-conflict-git-using-sourcetree
0 Stimmen
Das ist nicht spezifisch für diese Frage, aber ich musste irgendwo sagen, dass der Begriff "Konflikt" in der gängigen Sprache für Versionskontrollsysteme (VCS) sehr schlecht gewählt ist. Was wir in VCS als Konflikt bezeichnen, ist etwas völlig anderes als das, was wir normalerweise als Konflikt im wirklichen Leben sehen. Nehmen wir an, wir haben einen Autounfall. Der eine Fahrer sagt: "Oh, ich habe Sie nicht gesehen". Der andere sagt: "Ok, wir können das reparieren". Das ist überhaupt kein Konflikt. Der Konflikt kann erst danach auftreten. In VCS ist es genau umgekehrt: Die einfache Kollision wird als Konflikt bezeichnet, eine Änderung, die bewusst eine bekannte Änderung rückgängig macht, kann nicht einmal ein Konflikt sein.
0 Stimmen
Eine Reaktion auf meinen vorherigen Kommentar könnte lauten: "Wir wissen, dass es bei einem Git-Konflikt keinen wirklichen Konflikt gibt", aber es steckt mehr dahinter. Wenn Programmierer im Team arbeiten, gibt es Meinungsverschiedenheiten. Es kann vorkommen, dass ein Programmierer bewusst rückgängig macht, was ein anderer getan hat, und das käme einem echten Konflikt näher, aber Git-Konflikte haben nichts mit diesem Prozess zu tun. Wie auch immer, ich denke, der Begriff "Kollision" oder "Unfall" anstelle von "Konflikt" wäre näher an dem, was es tatsächlich ist, denn es passiert, wenn beide Seiten die andere Seite nicht kommen sehen.
0 Stimmen
Eine Nischenfrage zur Lösung eines Konflikts in nur einer Datei, von der Kommandozeile aus, unter Verwendung der dreifachen Zusammenführung mit einer bestimmten Strategie: stackoverflow.com/q/39126509/245966
0 Stimmen
Github.com bietet eine gute Möglichkeit, das Problem zu visualisieren. Stellen Sie sicher, dass Sie sehen este Antwort. (Es gibt auch Möglichkeiten, direkt von der Website aus zu bearbeiten und zu lösen, aber das ist nur eine Bequemlichkeit).
0 Stimmen
gist.github.com/karenyyng/f19ff75c60f18b4b8149 . Dieses Git-Mergetool-Tutorial könnte helfen.