Git Interactive Merge?

77

Ich habe zwei Zweige mit genau derselben Datei (falls Sie sich fragen, ob es sich um eine SQL-Datei handelt) und möchte sie interaktiv zusammenführen.

Ich möchte ein Diff-Programm wie bei einem Konflikt (oder einer Befehlszeile) öffnen und genau auswählen, welche Zeilen wohin führen.

Gibt es sowieso etwas zu tun?

Steven
quelle

Antworten:

84

Ja, aber meistens geschieht dies manuell. Sie werden Git mitteilen, dass Sie die beiden relevanten Zweige zusammenführen, aber nicht versuchen sollten, das Ergebnis selbst festzuschreiben ( bearbeitet, um hinzuzufügen: noch schnell vorzuspulen, wenn die Zusammenführung für trivial gehalten wird):

git merge --no-commit --no-ff branch-to-merge

Dann werden Sie git nach der Datei fragen, wie sie in den beiden Zweigen angezeigt wurde:

git show HEAD:filename >filename.HEAD
git show branch-to-merge:filename >filename.branch

und ihre Zusammenführungsbasis,

git show `git merge-base HEAD branch-to-merge`:filename  >filename.base

Sie werden sie mit einem beliebigen Tool zusammenführen (z.

meld filename.{HEAD,branch,base}

Sie werden das ( git add filename) inszenieren und dann die Zusammenführung ( git commit) festschreiben .

Phil Miller
quelle
2
Ich frage mich das Gleiche, Graham ... Ich habe es versucht git merge --no-commit branchund es wurde schließlich zusammengeführt ... Ich möchte, dass ich 3 oder 2 Dateien habe. Dass ich einen Diff verwenden und alles, was ich will, in diese Datei verschieben könnte.
Steven
Wenn Sie möchten, dass der ursprüngliche Zusammenführungsbefehl alles in Ruhe lässt und manuell ausgeführt wird, können Sie ihn aufrufen git merge -s ours, um alles so zu belassen, wie es sich in der aktuellen Verzweigung befindet. Dann müssen Sie jedoch sicherstellen, dass Änderungen in anderen Dateien vorgenommen werden.
Phil Miller
@Steven; Ich denke, die Idee ist, dass Sie die zusammengeführte Datei ignorieren und die HEAD- und Branch-Dateien verwenden, dh die "zwei Dateien", nach denen Sie suchen, sind HEAD: Dateiname und Branch-to-Merge: Dateiname.
Adrian Mouat
7
Git Gotcha: git merge --no-commit --no-ffwird überhaupt nichts begehen, siehe @ Brad-O Antwort unten. Sie müssen einschließen--no-ff
Ron Wertlen
1
@ Kootoopas: Ja
Phil Miller
41

Am einfachsten ist es git merge <other_branchdann git mergetool, die Konflikte grafisch zu lösen. Informationen zum Einrichten von mergetool finden Sie unter # 10935226.

Das Problem ist, dass Ihre geänderte Datei möglicherweise schnell mit der älteren Datei zusammengeführt wird. Dann muss man etwas schlauer werden.

Novelocrat bietet eine großartige Möglichkeit, etwas tiefer zu graben, aber Sie müssen häufig den ursprünglichen Befehl in ändern, git merge --no-commit --no-ff <other_branch>da --no-commit wirklich bedeutet "Übernehmen Sie die Zusammenführung nicht ... es sei denn, es handelt sich um eine Schnellvorlauf-Zusammenführung". Es ist ein bisschen wie ein Stachel für viele Leute, die versuchen, genau das zu tun, was Sie wollen.

Manchmal ist der am wenigsten verwirrende Weg nicht sehr elegant: Überprüfen Sie den anderen Zweig in einer anderen Arbeitskopie, verwenden Sie Ihr bevorzugtes Zusammenführungstool, um die gewünschte Version in das gewünschte Verzeichnis zu bringen, und legen Sie sie fest.

Brad O.
quelle
12
10935226 ist die Nummer dieser Frage. Was wolltest du dort schreiben?
Mathieu K.
32

Nach diesem Kern, wo Temp ein bestehender Zweig sein könnte.

https://gist.github.com/katylava/564416


Auf dem Meister:

git checkout -b temp

Auf temp:

git merge --no-commit --no-ff refactor

… Was alles inszeniert, also:

git reset HEAD

Fügen Sie dann die gewünschten Teile hinzu:

git add --interactive
Hugh
quelle
1
Dies funktionierte, aber ich musste 'Kopf' in 'Git Reset Head' weglassen, aber Git Reset funktionierte gut.
Micah
Ein Finale git commitführt keine Zusammenführung durch! - Wie beende ich die Zusammenführung am Ende?
Robert Siemer
@RobertSiemer Vielleicht können Sie in den nächsten Schritten normal zusammenführen: git co master; Git Merge Temp
Victor Choy
Der schöne Teil ist die patchOption von git add --interactive, mit der Sie Teile eines Diff inszenieren können, wie im Git-Buch beschrieben .
DJVG
29

Aus dem Zweig, in den Sie zusammenführen möchten:

git checkout -p branch_to_merge --

Dadurch wird branch_to_merge nicht ausgecheckt, sondern Sie können interaktiv Hunks aus dem Patch (diff) hinzufügen.

http://git-scm.com/docs/git-checkout

taj
quelle
1
Dies war sehr einfach für das interaktive Zusammenführen zu verwenden - danke!
cbcoutinho
Das macht genau das, wonach ich gesucht habe. Warum ist das nicht die akzeptierte Antwort?
Iliis
Dieser Befehl zeigt jedes "Stück" (Unterschiede in den Dateien, die eng zusammen gruppiert sind) und eine Option von "Ja" oder "Nein" an, um es zu verwenden oder nicht. Sehr hilfreich.
Mark Lakata
Für alles, was Sie in der Verzweigung getan haben und was nicht auf dem Master ist, wird davon ausgegangen, dass es gelöscht werden sollte. Das ist nicht die klügste Zusammenführungsstrategie.
Anne van Rossum
0

Sie können einfach WinMerge , DiffMerge oder ein verfügbares Diff / Merge-UI-Tool verwenden, um die Arbeit manuell auszuführen . Wenn Sie es in "git difftool" einbinden möchten, können Sie online nach Möglichkeiten suchen, wie diese Tools mit git funktionieren.

John Fisher
quelle
0

Der beste Weg, dies zu tun, ist:

  1. Überprüfen Sie die Filiale mit Ihren Änderungen
  2. Erstellen Sie ab diesem Punkt einen neuen Zweig
  3. Setzen Sie Ihren neuen Zweig auf das Commit zurück, mit dem Sie vergleichen und auf dem Sie aufbauen möchten. Das Zurücksetzen ist standardmäßig ein "gemischtes" Zurücksetzen, was bedeutet, dass der "Arbeitsbaum", dh die tatsächlichen Codedateien, nicht geändert werden
  4. Zu diesem Zeitpunkt zeigt mir mein Texteditor (VSCode), was sich zwischen meinen aktuellen Dateien und dem Commit unterscheidet, auf das ich zurückgesetzt habe. Ich kann den Code bearbeiten, um auszuwählen, welche Zeilen ich festschreiben möchte. Dadurch kann ich sehen, wie sich mein Zweig geändert hat, und jede Codezeile bestätigen, die ich festschreiben werde. Dies ist nützlich, z. B. bevor meine Änderungen wieder in die Produktion übernommen werden.
Dustin
quelle