Seit die Zeit git cherry-pick
gelernt hat, mehrere Commits anwenden zu können, wurde die Unterscheidung zwar etwas umstritten, aber dies ist etwas, das man als konvergente Evolution bezeichnen kann ;-)
Der wahre Unterschied liegt in der ursprünglichen Absicht, beide Werkzeuge zu erstellen:
git rebase
Die Aufgabe besteht darin, eine Reihe von Änderungen, die ein Entwickler in seinem privaten Repository vorgenommen hat und die gegen Version X eines Upstream-Zweigs erstellt wurden, auf Version Y desselben Zweigs (Y> X) weiterzuleiten. Dies ändert effektiv die Basis dieser Reihe von Commits und führt somit zu einer "Umbasierung".
(Es ermöglicht dem Entwickler auch, eine Reihe von Commits auf ein beliebiges Commit zu übertragen, dies ist jedoch weniger offensichtlich.)
git cherry-pick
dient dazu, ein interessantes Engagement von einer Entwicklungslinie in eine andere zu bringen. Ein klassisches Beispiel ist das Backportieren eines Sicherheitsupdates für einen instabilen Entwicklungszweig in einen stabilen (Wartungs-) Zweig, in dem a merge
keinen Sinn ergibt , da dies viele unerwünschte Änderungen mit sich bringen würde.
Seit seinem ersten Erscheinen git cherry-pick
konnten mehrere Commits gleichzeitig ausgewählt werden.
Der wahrscheinlich auffälligste Unterschied zwischen diesen beiden Befehlen besteht darin, wie sie den Zweig behandeln, an dem sie arbeiten: git cherry-pick
Bringt normalerweise ein Commit von einem anderen Ort und wendet es auf Ihren aktuellen Zweig an, zeichnet ein neues Commit auf, git rebase
nimmt Ihren aktuellen Zweig und schreibt ihn neu Eine Reihe eigener Tipps begeht auf die eine oder andere Weise. Ja, dies ist eine stark heruntergekommene Beschreibung dessen, was getan werden git rebase
kann, aber es ist beabsichtigt, zu versuchen, die allgemeine Idee zum Eintauchen zu bringen.
Aktualisieren Sie , um ein Beispiel für die Verwendung git rebase
zu erläutern.
In dieser Situation heißt es im
Buch :
Es gibt jedoch noch einen anderen Weg: Sie können den Patch der in C3 eingeführten Änderung übernehmen und erneut auf C4 anwenden. In Git wird dies als Rebasing bezeichnet. Mit dem Befehl rebase können Sie alle Änderungen, die in einem Zweig festgeschrieben wurden, auf einen anderen übertragen.
In diesem Beispiel würden Sie Folgendes ausführen:
$ git checkout experiment
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command
"Der Haken" hier ist, dass in diesem Beispiel der Zweig "Experiment" (das Thema für die Neubasierung) ursprünglich vom Zweig "Master" abgezweigt wurde und daher die Commits C0 bis C2 mit ihm teilt - effektiv ist "Experiment" " Master "bis einschließlich C2 plus Commit C3 darüber. (Dies ist der einfachste Fall. Natürlich kann "Experiment" mehrere Dutzend Commits zusätzlich zu seiner ursprünglichen Basis enthalten.)
Jetzt git rebase
wird gesagt, dass "Experiment" auf die aktuelle Spitze von "Master" zurückgesetzt werden soll, und es git rebase
geht so:
- Läuft, um
git merge-base
zu sehen, was das letzte Commit ist, das sowohl von "Experiment" als auch von "Master" geteilt wird (was ist der Sinn der Ablenkung, mit anderen Worten). Das ist C2.
- Spart alle seit dem Umleitungspunkt getätigten Commits; In unserem Spielzeugbeispiel ist es nur C3.
- Spult den KOPF zurück (der auf das Spitzen-Commit von "Experiment" zeigt, bevor die Operation ausgeführt wird), um auf die Spitze von "Master" zu zeigen - wir stützen uns darauf.
- Versucht, alle gespeicherten Commits (wie mit
git apply
) der Reihe nach anzuwenden . In unserem Spielzeugbeispiel ist es nur ein Commit, C3. Angenommen, seine Anwendung erzeugt ein Commit C3 '.
- Wenn alles gut gegangen ist, wird die Referenz "Experiment" aktualisiert, um auf das Commit zu verweisen, das sich aus dem Anwenden des zuletzt gespeicherten Commits ergibt (in unserem Fall C3 ').
Nun zurück zu Ihrer Frage. Wie Sie sehen können, wird hier technisch gesehen git rebase
eine Reihe von Commits von "Experiment" bis zur Spitze von "Master" transplantiert, sodass Sie zu Recht feststellen können, dass tatsächlich "ein anderer Zweig" im Prozess ist. Aber das Wesentliche ist, dass das Tip-Commit aus "Experiment" das neue Tip-Commit in "Experiment" war. Es hat nur seine Basis geändert:
Auch hier kann man technisch gesehen feststellen, dass git rebase
hier bestimmte Commits von "master" enthalten sind, und dies ist absolut korrekt.