2016-02-26 11 views
6

Ich bereite mich vor, eine Pull-Anfrage in einem Zweig einzuleiten, an dem ich gerade arbeite. Auf GitHub sehe ich, dass ich 5 Commits vor dem Master bin, also würde ich gerne meine Commits in eins zusammenfassen. Ich betreibe ein git log, um zu sehen, was die vorherigen Commits sind:Warum Git Rebase zeigt keine Commits Ich möchte Squash?

git log --oneline 

4363273 Updated Order_Entry with bulk UPDATE command 
e7e0c64 Updated Order Entry module and Orders Schema 
2cff23e Merge branch 'order_schema' 
104b2ce Orders Schema 
f7d57cf Order Entry updated to handle and log responses from LC 
afa1b7b Merge pull request #18 from project/bugfix/mockvenue 
4b2c8d8 Return correct string in mock venue API 

Jetzt glaube ich oben (4.363.273-f7d57cf) quetschen wollen Commits jene Top-5 aufgeführt. So laufe ich dann:

git rebase -i HEAD~5 

4363273 Updated Order_Entry with bulk UPDATE command 
pick 44768b2 Add script to run simulation on a strategy 
pick f82ec8d Implement mock venue 
pick f7d57cf Order Entry updated to handle and log responses from LC 
pick 4b2c8d8 Return correct string in mock venue API 
pick 104b2ce Orders Schema 
pick 4363273 Updated Order_Entry with bulk UPDATE command 

Wie kommt die Liste der nach dem Ausführen git rebase gezeigt Commits nicht die ersten 5 Commits übereinstimmen, wenn ich git log laufen. Vor allem, warum erscheinen e7e0c64 und 2cff23e in git log, aber nicht git rebase?

* 4363273 Updated Order_Entry with bulk UPDATE command 
* e7e0c64 Updated Order Entry module and Orders Schema 
|\ 
| * 2cff23e Merge branch 'order_schema' 
| |\ 
| | * 104b2ce Orders Schema 
| * | afa1b7b Merge pull request #18 from project/bugfix/mockvenue 
| |\ \ 
| | |/ 
| |/| 
| | * 4b2c8d8 Return correct string in mock venue API 
| |/ 
* | f7d57cf Order Entry updated to handle and log responses from LC 
|/ 
* 8ed2260 Merge pull request #17 from project/mockvenue 

enter image description here

+1

'git log' sortiert nach Datum (standardmäßig), aber' git rebase' muss (und verwendet) topologische Reihenfolge. Was passiert, wenn Sie "--graph" zu Ihrer 'git log --oneline' hinzufügen? (Die Verwendung von '--graph' zeigt ein Diagramm von Commits und erzwingt 'git log', um topologisch zu sortieren.) (Sie könnten auch '--decorate' hinzufügen, was Ihnen Verzweigungsnamen und ähnliches anzeigt, obwohl das bei Verwendung von' --all' interessanter ist als wenn es nicht verwendet wird.) – torek

+0

@torek Ich habe das Diagramm gepostet. Ich schaue durch und ich verstehe immer noch nicht, warum e7e0c64 und 2cff23e nicht erscheinen, wenn ich den Rebase-Befehl ausführe. – Brosef

Antwort

6

Ihre Grafik zeigt zahlreiche verschmilzt. Dies ist die Ursache des Problems. Es ist hier erwähnenswert, dass HEAD~5 bedeutet "fünf Schritte zurück nach --first-parent".


Lassen Sie uns zunächst ein wenig Hintergrund abdecken. Im Allgemeinen können Sie eine Zusammenführung nicht neu erstellen, und Rebase versucht es normalerweise nicht (normalerweise werden sie einfach verworfen). Die Verwendung von git rebase -p wird versuchen, Zusammenführungen beizubehalten, und wird oft erfolgreich sein, aber es ist sehr schwierig, interaktiv zu verwenden (da das Bearbeitungsskript keine Darstellung für Zusammenführungen hat).

Wir können mehr sehen, sobald wir verstehen, wie Rebase funktioniert. Nehmen wir an, wir haben eine Festschreibung Graph wie folgt aus:

  B - C - D <-- other-branch 
     /
... - A 
     \ 
      E - F - G <-- your-branch 
  1. Rebase nimmt eine Reihe von Commits und verwandelt sie in Changesets/patches. Das heißt, wenn Sie verpflichtet E, F und G, die folgen, begehen A, git ein Diff A-E produzieren müssen, dann E-F und schließlich F-G. Diese stellen dar, wie man von der Basisübergabe (die derzeit A ist) in die Spitze als eine Sequenz von Modifikationen umwandelt.

  2. Dann wechselt die Rebase zum neuen Basis-Commit, in diesem Fall commit , und wendet diese Patches nacheinander an. Die Änderung von A zu E, wie sie auf angewendet wird, macht ein neues Commit E'. Die Änderung von E zu F, angewendet auf E', macht ein neues Commit F'. Die letzte Änderung wird G'.

Ändern eines zu einem Patch commit (indem sie sie mit der Mutter Vergleich) und dann den Patch angewendet ist buchstäblich ein git cherry-pick. Mit anderen Worten, rebase ist nur eine Reihe von Pick-Operationen, Pick-Commits E, F und G auf einen neuen Zweig erstreckt sich von D. Die neue begehen Graph würde wie folgt aussehen:

  B - C - D <-- other-branch 
     /   \ 
... - A    E' - F' - G' <-- your-branch 
     \ 
      E - F - G [reflog only] 

Wenn wir begehen versuchen, diese gleiche Sache mit einer Zusammenführung zu tun, laufen wir in ein Problem.Eine Zusammenführung hat zwei (oder mehr) Eltern, und kann nicht ohne menschliche Hilfe ausgewählt werden: Sie müssen git cherry-pick sagen, welcher Elternteil derjenige ist, gegen den diff.

Was git rebase -p tut ist Redo die Zusammenführung, anstatt eine Kirsche-Pick versuchen. Das Fütterungsmaterial Dokumentation hat dieses Beispiel, in dem Sie A auf Q rebase könnten:

    X 
        \ 
       A---M---B 
      /
     ---o---O---P---Q 

Sie zeigen das Ergebnis nicht, aber es sollte so aussehen (idealerweise mit der ursprünglichen A--M--B Sequenz ausgegraut):

    X-------- 
        \  \ 
       A---M---B | 
      /   | 
     ---o---O---P---Q  | 
         \ | 
         A'--M'--B' 

Beachten Sie, dass neue M' begehen hat eine Zusammenführung zwischen A' und (unverändert) sein X begehen. Dies funktioniert, wenn die Zusammenführung eine normale (nicht "böse") Verschmelzung ist, aber zumindest ein bisschen knifflig ist.


zurück auf die besondere Situation Lassen Sie bekommen, wo git log --graph unter den Text gegeben hat (was ich nur ein wenig geändert haben). Es ist ein bisschen schwer, sich seitwärts zu drehen (die anderen Graphiken oben haben Vorgänger-Commits auf der linken Seite und Nachfolger auf der rechten Seite, während die Ausgabe git log --graph Vorgänger unten und Nachfolger oben hat), aber ich werde einen kurzen Stich machen, indem ich hinzufüge Ein-Buchstaben-Codes für jede begehen:

H * 4363273 Updated Order_Entry with bulk UPDATE command 
G * e7e0c64 Updated Order Entry module and Orders Schema 
    |\ 
F | * 2cff23e Merge branch 'order_schema' 
    | |\ 
E | | * 104b2ce Orders Schema 
D | * | afa1b7b Merge pull request #18 from project/bugfix/mockvenue 
    | |\ \ 
    | | |/ 
    | |/| 
C | | * 4b2c8d8 Return correct string in mock venue API 
    | |/ 
B * | f7d57cf Order Entry updated to handle and log responses from LC 
    |/ 
A * 8ed2260 Merge pull request #17 from project/mockvenue 

Jetzt mit A als die am weitesten links stehenden begehen und H als ganz rechts:

C---D 
    /___/ \ 
    //__--E-F 
///  \ 
A-----B-----G--H 

die direkte (first-parent) Ahnenreihe geht von H zu G, dann zu B, dann zu A. Das bedeutet, dass HEAD~5 ist ein begehen wir (zwei links von A) nicht einmal sehen kann, und git rebase -i HEAD~5alle dieser Commits mit Ausnahme verschmilzt Liste sollte (D, F und G). Das wären fünf Commits: A, B, C, E und H. Aber basierend auf seiner Protokollnachricht ist A auch eine Zusammenführung. Uns fehlen hier Informationen und es kann nicht das komplette Diagramm gezeichnet werden (was ebenso gut ist, da das kompakte Formular Lot Zeilen enthält).

In jedem Fall ist dies in der Tat, was passiert. Die rebase Befehl wird verpflichtet Cherry-pick von jedem von der Spitze erreichbar commit Auflisten commit (HEAD, die H commit ist), die nicht erreichbar von den ersten commit (HEAD~5 ausgeschlossen ist, eine Festschreibung zwei Schritte links von A, damit wir es nicht sehen können). Anschließend werden Zusammenführungs-Commits ausgelöst und alle verbleibenden Commits ausgewählt, um einen neuen, linearen Zweig zu erstellen.

Ob dies sinnvoll ist, und welche Festlegungen Sie treffen sollten, ist nicht etwas, das jemand anderes für Sie beantworten kann.

+1

Wow. Danke für diese Erklärung. Hat mir wirklich etwas Klarheit gegeben. Ich dachte, ich hätte Rebase verstanden, aber klar ist da noch viel mehr. Also in meinem Graph, den Sie alphabetisiert haben, werden die Commits A, D, F und G nicht angezeigt, wenn ich die Rebase starte, weil es sich um Merge-Commits handelt? – Brosef

+0

Ja (Entschuldigung wegen verspäteter Antwort, ich war auf einem Wochenendausflug). – torek

Verwandte Themen