Der Befehl git rebase hat den Ruf, magischer Git-Voodoo zu sein, von dem Anfänger sich fernhalten sollten, aber es kann einem Entwicklungsteam das Leben erheblich erleichtern, wenn es vorsichtig verwendet wird. In diesem Artikel vergleichen wir git rebase mit dem zugehörigen git merge Befehl und identifizieren alle möglichen Möglichkeiten, Rebasing in den typischen Git-Workflow zu integrieren.,

Konzeptionelle Übersicht

Das erste, was man über git rebase versteht, ist, dass es das gleiche Problem löst wie git merge. Beide Befehle sind so konzipiert, Änderungen von einem Zweig in einen anderen Zweig zu integrieren—sie tun es nur auf sehr unterschiedliche Weise.

Überlegen Sie, was passiert, wenn Sie mit der Arbeit an einer neuen Funktion in einem dedizierten Zweig beginnen, und ein anderes Teammitglied aktualisiert den Zweig master mit neuen Commits. Dies führt zu einem gegabelten Verlauf, der jedem bekannt sein sollte, der Git als Collaboration-Tool verwendet hat.,

Angenommen, die neuen Commits in master sind relevant für die Funktion, an der Sie arbeiten. Um die neuen Commits in Ihren feature Zweig zu integrieren, haben Sie zwei Möglichkeiten: Zusammenführen oder Rebasing.,

Die Merge-Option

Am einfachsten ist es, den master Zweig in den Feature-Zweig mit etwas wie dem folgenden zusammenzuführen:

git checkout feature git merge master

Oder Sie können dies zu einem Einzeiler verdichten:

 git merge feature master

Dadurch wird ein neues „Merge-Commit“ im feature Zweig, der die Geschichte beider Zweige zusammenbindet und Ihnen eine Verzweigungsstruktur gibt, die so aussieht:

Das Zusammenführen ist nett, weil es eine zerstörungsfreie Operation ist. Die bestehenden Filialen werden in keiner Weise verändert., Dies vermeidet alle möglichen Fallstricke beim Rebasing (siehe unten).

Andererseits bedeutet dies auch, dass der Zweig feature jedes Mal, wenn Sie Upstream-Änderungen einbeziehen müssen, ein fremdes Merge-Commit hat. Wenn master sehr aktiv ist, kann dies den Verlauf Ihres Feature-Zweigs erheblich verschmutzen. Während es möglich ist, dieses Problem mit erweiterten git log Optionen zu mildern, kann es anderen Entwicklern schwer fallen, den Verlauf des Projekts zu verstehen.,

Die Rebase-Option

Alternativ zum Zusammenführen können Sie den Zweig feature mit den folgenden Befehlen auf master umbasieren:

git checkout feature git rebase master

Hiermit wird der gesamte Zweig feature verschoben, um an der Spitze des master Zweig, der effektiv alle neuen Commits in master. Anstatt jedoch ein Merge-Commit zu verwenden, schreibt Rebasing den Projektverlauf neu, indem für jedes Commit im ursprünglichen Zweig brandneue Commits erstellt werden.,

Der Hauptvorteil des Rebasings besteht darin, dass Sie einen viel saubereren Projektverlauf erhalten. Erstens werden die unnötigen Merge-Commits eliminiert, die von git merge. Zweitens, wie Sie im obigen Diagramm sehen können, führt das Rebasing auch zu einem perfekt linearen Projektverlauf—Sie können der Spitze von feature bis zum Anfang des Projekts folgen Gabeln. Dies erleichtert die Navigation in Ihrem Projekt mit Befehlen wie git log, git bisect und gitk.,

Aber es gibt zwei Kompromisse für diese unberührte Commit-Geschichte: Sicherheit und Rückverfolgbarkeit. Wenn Sie die Goldene Regel des Rebasings nicht befolgen, kann das Neuschreiben des Projektverlaufs für Ihren Workflow in der Zusammenarbeit möglicherweise katastrophal sein. Und, noch weniger wichtig, das Rebasing verliert den Kontext, der durch ein Merge-Commit bereitgestellt wird—Sie können nicht sehen, wann Upstream-Änderungen in die Funktion integriert wurden.

Interaktives Rebasing

Interaktives Rebasing gibt Ihnen die Möglichkeit, Commits zu ändern, wenn sie in den neuen Zweig verschoben werden., Dies ist noch leistungsfähiger als eine automatisierte Rebase, da sie die vollständige Kontrolle über den Commit-Verlauf des Zweigs bietet. In der Regel wird dies verwendet, um einen unordentlichen Verlauf zu bereinigen, bevor ein Feature-Zweig in master.,

Um eine interaktive Rebasing-Sitzung zu starten, übergeben Sie die Option i an den Befehl git rebase:

git checkout feature git rebase -i master

Dadurch wird ein Texteditor geöffnet, in dem alle Commits aufgelistet sind, die verschoben werden sollen:

pick 33d5b7a Message for commit #1 pick 9480b3d Message for commit #2 pick 5c67e61 Message for commit #3

listing definiert genau, wie der Zweig nach der Rebase aussehen wird. Indem Sie den Befehl pick ändern und / oder die Einträge neu anordnen, können Sie den Verlauf des Zweigs so aussehen lassen, wie Sie möchten., Wenn das 2.Commit beispielsweise ein kleines Problem beim 1. Commit behebt, können Sie es mit dem Befehl fixup zu einem einzigen Commit verdichten:

pick 33d5b7a Message for commit #1 fixup 9480b3d Message for commit #2 pick 5c67e61 Message for commit #3

Wenn Sie die Datei speichern und schließen, führt Git die Rebase gemäß Ihren Anweisungen aus, was zu einem Projektverlauf führt, der wie folgt aussieht:

iv id = “ unbedeutende Commits wie diese machen den Verlauf Ihrer Funktion viel einfacher zu verstehen. Dies ist etwas, das git merge einfach nicht kann.,

Die goldene Regel des Rebasing

Sobald Sie verstehen, was Rebasing ist, ist das Wichtigste zu lernen, wann es nicht zu tun ist. Die goldene Regel von git rebase ist, es niemals in öffentlichen Zweigen zu verwenden.

Denken Sie zum Beispiel darüber nach, was passieren würde, wenn Sie master auf Ihre feature Verzweigung:

Die Rebase verschiebt alle Commits in master auf die Spitze von feature. Das Problem ist, dass dies nur in Ihrem Repository passiert ist., Alle anderen Entwickler arbeiten noch mit dem Original master. Da das Rebasing zu brandneuen Commits führt, wird Git der Meinung sein, dass der Verlauf Ihres master – Zweigs von dem aller anderen abweicht.

Die einzige Möglichkeit, die beiden master – Zweige zu synchronisieren, besteht darin, sie wieder zusammenzuführen, was zu einem zusätzlichen Merge Commit und zwei Sets von Commits führt, die dieselben Änderungen enthalten (die ursprünglichen und die aus Ihrem rebased Zweig). Unnötig zu erwähnen, dass dies eine sehr verwirrende Situation ist.,

Bevor Sie also git rebase, fragen Sie sich immer: „Schaut sich noch jemand diesen Zweig an?“Wenn die Antwort ja lautet, nehmen Sie Ihre Hände von der Tastatur und denken Sie über eine zerstörungsfreie Möglichkeit nach, Ihre Änderungen vorzunehmen (z. B. den Befehl git revert). Andernfalls können Sie den Verlauf sicher so oft neu schreiben, wie Sie möchten.

Force-Pushing

Wenn Sie versuchen, den rebased master – Zweig zurück in ein Remote-Repository zu verschieben, verhindert Git dies, da dies mit dem Remote-Zweig master in Konflikt steht., Sie können den Push jedoch erzwingen, indem Sie das Flag --force wie folgt übergeben:

# Be very careful with this command! git push --force

Dies überschreibt den Remote-Zweig master, der mit dem neu erstellten Zweig aus Ihrem Repository übereinstimmt, und macht die Dinge für den Rest Ihres Teams sehr verwirrend. Seien Sie also sehr vorsichtig, diesen Befehl nur zu verwenden, wenn Sie genau wissen, was Sie tun.

Eines der wenigen Male, die Sie erzwingen sollten, ist, wenn Sie eine lokale Bereinigung durchgeführt haben, nachdem Sie einen privaten Feature-Zweig in ein Remote-Repository verschoben haben (z. B. zu Sicherungszwecken)., Das ist wie zu sagen: „Hoppla, ich wollte diese ursprüngliche Version des Feature-Zweigs nicht wirklich pushen. Nimm stattdessen den aktuellen.“Auch hier ist es wichtig, dass niemand von den Commits der ursprünglichen Version des Feature-Zweigs abarbeitet.

Workflow Walkthrough

Rebasing kann so viel oder so wenig in Ihren vorhandenen Git-Workflow integriert werden, mit dem Ihr Team vertraut ist. In diesem Abschnitt werfen wir einen Blick auf die Vorteile, die das Rebasing in den verschiedenen Phasen der Entwicklung eines Features bieten kann.,

Der erste Schritt in jedem Workflow, der git rebase nutzt, besteht darin, für jedes Feature einen dedizierten Zweig zu erstellen. Dies gibt Ihnen die notwendige Verzweigungsstruktur, um Rebasing sicher zu nutzen:

Lokale Bereinigung

Eine der besten Möglichkeiten, Rebasing in Ihren Workflow zu integrieren, besteht darin, lokale, laufende Funktionen zu bereinigen. Durch regelmäßige Durchführung einer interaktiven Rebase können Sie sicherstellen, dass jedes Commit in Ihrer Funktion fokussiert und sinnvoll ist., Auf diese Weise können Sie Ihren Code schreiben, ohne sich Gedanken darüber zu machen, ihn in isolierte Commits aufzuteilen—Sie können ihn danach beheben.

Wenn Sie git rebase aufrufen, haben Sie zwei Optionen für die neue Basis: Den übergeordneten Zweig des Features (z. B. master) oder einen früheren Commit in Ihrem Feature. Wir haben ein Beispiel für die erste Option im Abschnitt Interaktives Rebasing gesehen. Die letztere Option ist schön, wenn Sie nur die letzten Commits beheben müssen. Mit dem folgenden Befehl wird beispielsweise eine interaktive Rebase nur der letzten 3 Commits gestartet.,

git checkout feature git rebase -i HEAD~3

Indem Sie HEAD~3 als neue Basis angeben, verschieben Sie den Zweig nicht wirklich—Sie schreiben nur interaktiv die 3 Commits neu, die ihm folgen. Beachten Sie, dass dies keine Upstream-Änderungen in den Zweig feature.

Wenn Sie die gesamte Funktion mit dieser Methode neu schreiben möchten, kann der Befehl git merge-base nützlich sein, um die ursprüngliche Basis des Zweigs feature zu finden., Das Folgende gibt die Commit-ID der ursprünglichen Basis zurück, die Sie dann an git rebaseübergeben können:

git merge-base feature master

Diese Verwendung von interaktivem Rebasing ist eine großartige Möglichkeit, git rebase in Ihren Workflow einzuführen, da dies nur lokale Zweige betrifft. Das einzige, was andere Entwickler sehen werden, ist Ihr fertiges Produkt, das ein sauberer, leicht zu verfolgender Funktionszweigverlauf sein sollte.

Aber auch hier funktioniert dies nur für private Feature-Zweige., Wenn Sie über denselben Feature-Zweig mit anderen Entwicklern zusammenarbeiten, ist dieser Zweig öffentlich und Sie dürfen seinen Verlauf nicht neu schreiben.

Es gibt keine git merge Alternative zum Bereinigen lokaler Commits mit einer interaktiven Rebase.

Upstream-Änderungen in ein Feature integrieren

Im Abschnitt Konzeptionelle Übersicht haben wir gesehen, wie ein Feature-Zweig Upstream-Änderungen von master mithilfe von git merge oder git rebaseintegrieren kann., Das Zusammenführen ist eine sichere Option, die den gesamten Verlauf Ihres Repositorys beibehält, während das Rebasing einen linearen Verlauf erstellt, indem Sie Ihren Feature-Zweig auf die Spitze von master.

Diese Verwendung von git rebase ähnelt einer lokalen Bereinigung (und kann gleichzeitig durchgeführt werden), enthält jedoch dabei die Upstream-Commits von master.

Beachten Sie, dass es vollkommen legal ist, auf einen Remote-Zweig anstelle von masterneu zu skalieren., Dies kann passieren, wenn Sie an derselben Funktion mit einem anderen Entwickler zusammenarbeiten und deren Änderungen in Ihr Repository integrieren müssen.,

Wenn Sie und ein anderer Entwickler namens John beispielsweise Commits zum Zweig feature hinzugefügt haben, sieht Ihr Repository nach dem Abrufen des Remote-Zweigs feature aus Johns Repository wie folgt aus:

Sie können diesen Fork genauso auflösen, wie Sie Upstream-Änderungen von master: Führen Sie entweder Ihre lokale feature mit john/feature zusammen oder setzen Sie Ihre lokale feature auf die Spitze von john/feature.,

Beachten Sie, dass diese Rebase nicht gegen die Goldene Regel des Rebasings verstößt, da nur Ihre lokalen feature—Commits verschoben werden-alles davor ist unberührt. Das ist wie zu sagen: „Füge meine Änderungen zu dem hinzu, was John bereits getan hat.“In den meisten Fällen ist dies intuitiver als die Synchronisierung mit dem Remote-Zweig über ein Merge-Commit.

Standardmäßig führt der Befehl git pull eine Zusammenführung aus, Sie können jedoch die Integration des Remote-Zweigs in eine Rebase erzwingen, indem Sie ihm die Option --rebase.,

Überprüfen einer Funktion mit einer Pull-Anforderung

Wenn Sie Pull-Anforderungen als Teil Ihres Code-Überprüfungsprozesses verwenden, müssen Sie nach dem Erstellen der Pull-Anforderung die Verwendung von git rebase vermeiden. Sobald Sie die Pull-Anforderung stellen, werden andere Entwickler Ihre Commits betrachten, was bedeutet, dass es sich um einen öffentlichen Zweig handelt. Das Neuschreiben des Verlaufs macht es Git und Ihren Teamkollegen unmöglich, Follow-up-Commits zu verfolgen, die der Funktion hinzugefügt wurden.

Alle Änderungen von anderen Entwicklern müssen mit git merge anstelle von git rebase.,

Aus diesem Grund ist es normalerweise eine gute Idee, Ihren Code mit einer interaktiven Rebase zu bereinigen, bevor Sie Ihre Pull-Anfrage senden.

Integration eines genehmigten Features

Nachdem ein Feature von Ihrem Team genehmigt wurde, haben Sie die Möglichkeit, das Feature auf die Spitze des Zweigs master zu setzen, bevor Sie git merge verwenden, um das Feature in die Hauptcodebasis zu integrieren.,

Dies ist eine ähnliche Situation wie das Einbinden von Upstream-Änderungen in einen Feature-Zweig, aber da Sie Commits im master – Zweig nicht neu schreiben dürfen, müssen Sie schließlich git merge, um das Feature zu integrieren. Wenn Sie jedoch vor der Zusammenführung eine Rebase durchführen, können Sie sicher sein, dass die Zusammenführung schnell weitergeleitet wird, was zu einem perfekt linearen Verlauf führt. Dies gibt Ihnen auch die Möglichkeit, Follow-up-Commits, die während einer Pull-Anforderung hinzugefügt wurden, zu quetschen.,

Wenn Sie mit git rebase nicht ganz vertraut sind, können Sie die Rebase immer in einem temporären Zweig durchführen. Auf diese Weise können Sie den ursprünglichen Zweig überprüfen und es erneut versuchen, wenn Sie versehentlich den Verlauf Ihrer Funktion durcheinander bringen. Zum Beispiel:

git checkout feature git checkout -b temporary-branch git rebase -i master # git checkout master git merge temporary-branch

Inhaltsangabe

Und das ist alles, was Sie wirklich wissen müssen, um zu beginnen Rebase Ihre Filialen., Wenn Sie einen sauberen, linearen Verlauf ohne unnötige Merge-Commits bevorzugen, sollten Sie bei der Integration von Änderungen aus einem anderen Zweig nach git rebase anstelle von git merge.

Wenn Sie andererseits den gesamten Verlauf Ihres Projekts beibehalten und das Risiko vermeiden möchten, öffentliche Commits neu zu schreiben, können Sie sich an git merge. Beide Optionen sind vollkommen gültig, aber zumindest haben Sie jetzt die Möglichkeit, die Vorteile von git rebase.