2013-05-10 17 views
7

Ich werde ratlos, wenn git diff other_branch Unterschiede zeigt und git merge other_branch nichts tut. Was ist der richtige Weg, um diesen "fehlenden" Code in my_branch einzubauen?Was ist der richtige Weg zum Zusammenführen von Zweigen, wenn `git diff` Änderungen zeigt, aber` git merge` nichts tut

Diese SO answer Diagramm eine ähnliche Situation wie meine.

o---A---B---C-------G my_branch 
    \  \ /
     --*D*---E---F other_branch 

ändert sich überraschenderweise in D werden nicht automatisch in my_branch zusammengeführt, wenn ich

git checkout my_branch 
git merge other_branch 

in F-G Ich kann manually create a patch

Natürlich zu bringen und wenden Sie es an my_branch an, so:

git diff other_branch my_branch > patchfile 
git checkout my_branch 
git patch -p1 < patchfile 

Aber ich möchte das richtig machen, ohne den Git Log aufzumotzen. Mit dem Patch-Ansatz zeichnet git die Änderungen in D auf und mein letzter Patch geschieht unabhängig voneinander (Code-Churn). Ich möchte die git log vereinfachen und sicherstellen, dass andere nicht unbeabsichtigte Dinge passieren (leise und heimtückisch), wenn sie eine git merge my_branch tun.

+2

Haben Sie versucht, 'my_branch' in' other_branch' einzufügen? Wahrscheinlich könnte das die Unterschiede auflösen. Wenn einige Commits in 'my_branch' zurückgesetzt wurden, aber nicht in' other_branch', werden Sie in einer Situation wie dieser landen. – iltempo

+0

@iltempo, ich habe versucht, die Zusammenführung nach Ihrem Kommentar, und ja, es hat tatsächlich die Unterschiede aufgelöst und der Git-Diff ist jetzt sauber. Ich muss nur darauf vertrauen, dass es richtig verschmolzen ist. – hobs

+0

@iltempo, ich habe nicht absichtlich jede Änderung in 'my_branch' zurückgenommen, aber kann sehr gut haben - indem ich in sublime (Texteditor) nach dem Oszillieren zwischen Checkouts und Edits und Checkouts mit Commits zwischengespeichert habe. Ich muss vorsichtiger sein. – hobs

Antwort

2

Sie scheinen hier zwei Probleme gleichzeitig zu haben.

Unter der Annahme, eine Geschichte wie die, die Sie beschrieben:

   my_branch 
        v 
----A---B---C-------G 
    \  \ /
     --*D*---E---F 
       ^
      other_branch 

Warum der Unterschied nicht leer ist:

Diese Situation durch die Befehle erzeugt wird, die Sie erwähnt, das heißt sein auf my_branch und dann tun git merge other_branch. Diese Aktion führte zu einem Zusammenführungs-Commit G und verschoben den aktuellen Zweig (my_branch) vorwärts, aber links other_branch wo es war. So funktioniert die Zusammenführung immer! Natürlich gibt es an dieser Stelle noch einen Unterschied zwischen my_branch (G) und other_branch (F) - sie weisen doch auf unterschiedliche Commits hin.

Wenn Sie die beiden Zweige identisch sein wollen, Sie other_branch auf folgende Weise bewegen kann:

  1. git checkout other_branch; git merge my_branch - das ist ein vorspulen merge seit G ist ein Nachkomme von F
  2. [während nicht auf other_branch!] git branch -D other_branch; git branch other_branch my_branch - das wird other_branch entfernen und sie dann an der gleichen Stelle wieder zu schaffen, wo my_branch derzeit
  3. git checkout other_branch; git reset --hard my_branch - das wird bewegenother_branch genau zu zeigen, wo my_branch derzeit zeigen

Nach tun ein dieser Schritte, beide my_branch und other_branch werden auf G zeigen.


Warum die Änderungen von D begehen, sind nicht in my_branch (G)

Git Geschichten verschmilzt, nicht ändert. Das bedeutet normalerweise, dass Git die beiden Seiten einer Zusammenführung (und, falls verfügbar, ihre jüngste gemeinsame Vorfahrenübergabe, aka die merge-base) nimmt und versucht, sie zu kombinieren. Da Git-Commits sind Snapshots, nicht changesets/deltas/diffs, das ist keine Information über andere Commits oder Änderungen in der tatsächlichen Zusammenführung verwendet.

Mithilfe der Zusammenführungs-Basis führt Git eine so genannte Drei-Wege-Zusammenführung durch, wobei der gemeinsame Vorgänger verwendet wird, um die Änderungen auf beiden Seiten intelligent zu lösen. Wenn dies nicht möglich ist, wird die Zusammenführung unterbrochen und der Benutzer muss die Konflikte lösen.

Was ist passiert in Ihrer Geschichte wahrscheinlich ist, dass entweder begehen E oder F rückgängig gemacht (oder overrode) die Änderungen von D - dies während der Zusammenführung passiert sein könnte, die in FE oder tatsächliche (manuell) Änderungen erzeugt.

Wie Sie selbst in einem Kommentar erwähnt haben, wechseln Sie häufig zwischen Commits und Änderungen. Sie werden dadurch vielfache Änderungen vornehmen (Git überträgt nicht festgeschriebene Änderungen während des Checkouts), was es sehr schwierig machen kann zu sagen, wohin die Änderungen gehen sollen und wohin sie gehen. Versuchen Sie, dies zu vermeiden, indem Sie vor dem Ändern der Verzweigungen Änderungen vornehmen oder git stash verwenden, um sie zu puffern.

Verwandte Themen