2016-04-19 5 views
1

Hier ist ein reproduzierbares Beispiel für das Problem, das ich mich da eingelassen habe:Wiederzusammenführung nach "Selective" oder "Partial" Merge

Setup-

mkdir test-git 
cd test-git 
git init 
echo 'Hello, world.' > file1.txt 
git add . 
git commit -m 'init commit' 
git branch branch2 
git checkout branch2 
echo 'Hello, universe' > file1.txt 
echo 'Foobar' > file2.txt 
git add . 
git commit -m 'commit 2' 

ich branch2 in Master fusionieren wollte sondern nur die Änderungen an file1.txt, also hier, was ich tat:

git checkout master 
git merge branch2 --no-commit --no-ff 
git reset -- file2.txt 
git commit -m 'Partially Merged Branch2 into Master!' 

also hier ist, wo ich erkennen, dass möglicherweise keine gute ide gewesen a ... Sagen wir, ich habe meine Meinung geändert und möchte nun auch file2.txt zusammenführen. Ich kann laufen:

git merge branch2 

Antwort: Bereits up-to-date.

Wenn ich git diff branch2 --name-status führen Sie es D file2.txt zurückkehrt, so dass ich denke, wenn ich unstaged file2.txt es dies als Löschung verfolgt? Ich verstehe immer noch nicht ganz, warum ich nicht verschmelzen kann, und es würde die Datei nicht hinzufügen (ich verstehe den Mischalgorithmus von Git offensichtlich nicht gut).

Leider ist mein derzeitiges Szenario viel komplizierter als das, so dass ich das Commit nicht genau rückgängig machen kann. Gibt es eine einfache Möglichkeit, die Unterschiede zwischen master und branch2, ohne Geschichte neu zu schreiben?

Antwort

2

In git soll ein Merge Commit alle notwendigen Änderungen von allen Eltern haben. Wenn also ein Committer sich bewusst dafür entschieden hat, eine bestimmte Version einer Datei wie Sie auszuwählen, dann wird das resultierende Commit als "eine richtige Zusammenführung" betrachtet und es ist unmöglich, "weitere Zusammenführung" durchzuführen.

Dieses Verhalten hat seine Gründe. Angenommen, man nimmt nach dem 1. Zusammenführungs-Commit eine weitere Änderung an file2.txt in branch2 vor und führt dann eine weitere Zusammenführung von branch2 in master durch (eine ziemlich typische Situation, nicht wahr?). Was sollte als ein korrekter Zustand von file2.txt betrachtet werden. Ich würde erwarten, dass die zweite Zusammenführung nur Änderungen zwischen zwei Zusammenführungen enthalten sollte, oder? Aber Sie wünschen ein anderes Verhalten, wenn git alle Änderungen bis file2.txt, die seit Beginn der Geschichte bisher nicht angewendet wurden, sammelt. Das wäre ziemlich nervig.

Trotzdem können Sie eine "alternative Zusammenführung" tun. Das heißt, zu einem Commit vor der Zusammenführung auf master Zweig (in Ihrem Beispiel 'init commit') springen und dann git merge noch einmal ausgeben.

Wenn das Umschreiben von Verlauf nicht Ihren Anforderungen entspricht, können Sie bei diesem Commit einen neuen Zweig b3 erstellen, die Zusammenführung durchführen und dann b3 zurück zum Master zusammenführen. Auf jeden Fall erhalten Sie einen Zusammenführungskonflikt unter file2.txt und sollten ihn lösen, indem Sie eine "richtige Variante" dafür bereitstellen.

+0

Ja das macht total Sinn. Obwohl ich jahrelang Git benutze, beginne ich zu erkennen, dass ich wirklich nicht so ein solides Verständnis habe, wie ich es getan habe. Würde Master nicht auf die Init-Festschreibung zurückgesetzt und dann die Geschichte der Umverursachungsursache neu geschrieben? – NSjonas

+0

In der Tat wird es. Die Antwort wurde aktualisiert. – user3159253