Git-Rebase-Parameter verstehen und auswendig lernen

11

Bisher ist der verwirrendste Teil von Git die Umbasierung auf einen anderen Zweig. Insbesondere die Befehlszeilenargumente sind verwirrend.

Jedes Mal, wenn ich ein kleines Stück eines Zweigs auf die Spitze eines anderen verzweigen möchte, muss ich die Dokumentation zur Git-Rebase überprüfen. Es dauert ungefähr 5-10 Minuten, um zu verstehen, was jedes der drei Hauptargumente sein sollte.

git rebase <upstream> <branch> --onto <newbase>

Was ist eine gute Faustregel, um mir zu merken, auf welche dieser drei Parameter bei jeder Art von Rebase auf einen anderen Zweig eingestellt werden soll?

Denken Sie daran, dass ich die Dokumentation zu git-rebase immer und immer wieder und immer wieder (und immer wieder) durchgesehen habe, aber es ist immer schwer zu verstehen (wie ein langweiliges wissenschaftliches Whitepaper oder so). An diesem Punkt habe ich das Gefühl, dass ich andere Menschen einbeziehen muss, um es zu verstehen.

Mein Ziel ist es, dass ich niemals die Dokumentation für diese grundlegenden Parameter überprüfen muss. Ich konnte sie mir bisher nicht merken und habe bereits eine Menge Rebases durchgeführt. Es ist also etwas ungewöhnlich, dass ich mir bisher jeden anderen Befehl und seine Parameter merken konnte, aber nicht mit --onto.

void.pointer
quelle
Sie können entweder einige Git-Aliase für Ihre allgemeinen Anwendungsfälle definieren oder ein Assistentenskript aufrufen, das Sie daran erinnert, was jeder der Parameter bedeutet, bevor Sie den Befehl ausführen.
Rory Hunter
4
Ah, diese umwerfenden, puren Eleganz der Git-Befehlsoptionen. So intuitiv zu bedienen. Immer ein echtes Vergnügen.
JensG

Antworten:

9

Lassen Sie uns --ontofür den Moment überspringen . upstreamund branchsind ziemlich einfach und tatsächlich eine Art Nachahmung checkoutund branch- das zweite Argument ist optional:

git branch <newbranch>
git branch <newbranch> <base>
git checkout -b <newbranch>
git checkout -b <newbranch> <base>
git rebase <upstream>
git rebase <upstream> <branch>

(Abgesehen, die Namen dieser Argumente rebase, „stromaufwärts“ und „Zweig“ sind nicht sehr aussagekräftig IMO Ich denke an sie in der Regel wie peachoftree. <start>Und <end>, das ist , wie ich sie verwenden werden: git rebase <start> <end>)

Wenn der zweite Zweig weggelassen wird, entspricht das Ergebnis fast dem ersten Auschecken dieses Zweigs und dem anschließenden Ausführen dieses Zweigs, als hätten Sie diesen Zweig nicht angegeben. Die Ausnahme ist branch, dass sich Ihr aktueller Zweig nicht ändert:

git checkout <base> && git branch <newbranch> && git checkout <previous_branch>
git checkout <base> && git checkout -b <newbranch>
git checkout <end>  && git rebase <start>

Um zu verstehen, was rebasebeim Aufrufen geschieht, habe ich es zunächst als eine besondere Art der Zusammenführung betrachtet. Es ist nicht wirklich, aber es hat geholfen, als ich anfing, Rebase zu verstehen. Um das Beispiel von peachoftree auszuleihen:

A--B--F--G master
    \
     C--D--E feature

Ein git merge masterErgebnis in diesem:

A--B--F-----G master
    \        \
     C--D--E--H feature

Während a git rebase master(während auf dem Zweig feature!) Daraus resultiert:

A--B--F--G master
          \
           C'--D'--E' feature

In beiden Fällen featureenthält jetzt Code von beiden masterund feature. Wenn Sie nicht aktiviert sind feature, können Sie mit dem zweiten Argument als Verknüpfung zu diesem Argument wechseln: Es git rebase master featurewird dasselbe wie oben ausgeführt.


Nun zum Special --onto. Der wichtige Teil, an den Sie sich erinnern sollten, ist, dass der Standardwert verwendet wird, <start>wenn nichts angegeben ist. Wenn ich oben --ontospeziell spezifiziere , würde dies zu demselben Ergebnis führen:

git rebase --onto master master
git rebase --onto master master feature

(Ich verwende es nicht --ontoohne Angabe, <end>nur weil es einfacher ist, es mental zu analysieren, obwohl ich dachte, dass diese beiden gleich sind, wenn sie bereits aktiviert sind feature.)

Um zu sehen, warum dies --ontonützlich ist, finden Sie hier ein anderes Beispiel. Nehmen wir an, ich war eingeschaltet featureund habe einen Fehler bemerkt, den ich dann behoben habe - aber featureaus masterVersehen verzweigt hatte :

A--B--F--G master
    \
     C--D--E feature
            \
             H--I bugfix

Ich möchte diese Commits "verschieben", bugfixdamit sie nicht mehr abhängig sind feature. Bei jeder Art von Zusammenführung oder Neuausrichtung, die oben in dieser Antwort gezeigt wird, werden die drei featureCommits zusammen mit den beiden bugfixCommits verwendet.

Zum Beispiel git rebase master bugfixist falsch. Der Bereich <start>um <end>geschieht von allen Commits umfassen feature, die auf der Oberseite der wiedergegeben werden master:

A--B--F--G master
    \     \
     \     C'--D'--E'--H'--I' bugfix
      \
       C--D--E feature

Was wir eigentlich wollen, ist die Bandbreite der Commits feature, bugfixdie zusätzlich abgespielt werden sollen master. Dafür ist das vorgesehen --onto- Angabe eines anderen "Wiederholungs" -Ziels als der "Start" -Zweig:

git rebase --onto master feature bugfix

A--B--F--G master
    \     \
     \     H'--I' bugfix
      \
       C--D--E feature
Izkata
quelle
1

Nur eine Auffrischung, Rebasing ist hauptsächlich dann gedacht, wenn Ihr Commit-Verlauf linear erscheinen soll, wenn sich zwei Zweige unabhängig voneinander entwickelt haben. Im Grunde wird der Commit-Verlauf neu geschrieben.

so wie ich es gerne mache ist git rebase --onto <target branch> <start branch> <end branch>

Wo <target branch>sich der Zweig befindet, auf den Sie neu gründen, <start branch>ist normalerweise der Zweig, von dem Sie sich trennen, <end branch>und <end branch>der Zweig, auf den Sie sich neu stützen.

wenn Sie mit beginnen

A--B--F--G master
    \
     C--D--E feature

und TU

git rebase --onto master master feature

Sie erhalten

A--B--F--G master
          \
           C'--D'--E' feature

Eine weitere gute Sache, die Sie wissen sollten, ist die <target branch>Standardeinstellung, <start branch>sodass Sie dieselbe Rebase wie ausführen können

git rebase --onto master feature

Wenn Sie weitere Hilfe benötigen, lesen Sie die Anleitung Rebase ohne Tränen

Pfirsichbaum
quelle
Ihr Ergebnis sieht irreführend aus. Rebase sollte den masterZweig selbst unverändert lassen. Sie erhalten nur eine Funktion, die sich verzweigt, G--C'--D'--E'während Sie masternoch bei anhalten G.
Frank
@Frank, ich habe das getan, um die ganze Sache mit der linearen Geschichte zu betonen, aber jetzt denke ich, dass dein Weg besser ist. Fest.
Pfirsichbaum
1
Können Sie ein Beispiel zeigen, wo <target branch>und wo <start branch>es anders ist, um den Lesern das Verständnis des allgemeinsten Falls zu erleichtern?
Rufflewind