git rebase
Definition
Rebasing bedeutet, eine Reihe von Commits auf einen neuen Basis-Commit zu verschieben oder zusammenzuführen. Anders gesagt, wird die Grundlage des aktuellen Branches von einem Commit auf einen anderen geändert, sodass es so aussieht, als wäre der Branch aus einem anderen Commit erstellt worden. Dies geschieht durch Ausführen des Befehls git rebase. Beachte, dass der Branch zwar gleich aussehen kann, er jedoch aus vollständig neuen Commits aufgebaut ist.

Verwendung des git rebase-Befehls
Zunächst brauchen wir diesen Befehl, um eine lineare Projektgeschichte beizubehalten. Zum Beispiel entwickelt sich der Master-Branch weiter, nachdem du mit der Arbeit an einem Feature-Branch begonnen hast. Du brauchst die neuesten Aktualisierungen des Master-Branches in deinem Feature-Branch, aber die Historie des Master-Branches muss sauber bleiben. Wir brauchen eine klare Historie bei der Ausführung von Git-Operationen, um Regressionen nachverfolgen zu können. Weitere Informationen zur Verwendung von git rebase findest du unten:
Die Unzulässigkeit des Rebasings öffentlicher Historie
Rebase niemals Commits, nachdem du sie in der öffentlichen Historie veröffentlicht hast. Wie beim Ändern und Zurücksetzen führt das zu Problemen bei der Zusammenarbeit im Team. Wenn du es tust, wird der alte Commit durch einen neuen ersetzt, und es sieht so aus, als wäre ein Teil deines Projekts verschwunden.
Der Unterschied zwischen standardmäßigem Git rebase und interaktivem Git rebase.
Es gibt zwei Modi des git rebase-Befehls: standard und interaktiv. Im Standardmodus wendet git rebase die Commits im aktuellen Arbeits-Branch automatisch auf den Head des übergebenen Branches an. Der aktuelle Branch wird auf <code><base></code> rebased. Das können verschiedene Arten von Commit-Referenzen sein, etwa ein Tag, eine ID, ein Branch-Name und so weiter.
git rebase command
git rebase <base>Im interaktiven Modus wird git rebase mit dem -i-Flag ausgeführt, das für „interactive“ steht. Der Vorteil des Rebasings im interaktiven Modus besteht darin, einzelne Commits während des Vorgangs zu ändern, ohne alle Commits auf die neue Basis verschieben zu müssen. Dank dieses Modus kannst du die Historie bereinigen, indem du die vorhandene Abfolge von Commits entfernst und änderst.
Das Ausführen des folgenden Befehls öffnet einen Editor:
git rebase -i
git rebase --interactive <base>Gib in diesem Editor die unten angegebenen Befehle für jeden Commit ein, der rebased werden muss. Git beginnt dann, Commits erneut abzuspielen und die Rebase-Befehle anzuwenden, nachdem die Befehle für jeden Commit bestimmt wurden.
git rebase example
pick 11a1456 some old commit
pick a23db19 Adds new feature
# Rebase 31d332c..a23db19 onto 31d332c (9 commands)
#
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commitInteraktive Rebase-Befehle
Während eines interaktiven Rebase kannst du für jeden Commit in der Todo-Liste die folgenden Befehle verwenden:
drop: Verwirft den Commit aus dem endgültigen zusammengeführten Commit-Block während des erneuten Abspielens.pick: Behält den Commit unverändert bei, ohne die Nachricht oder den Inhalt zu bearbeiten, und lässt ihn als einzelnen Commit in der Branch-Historie.exec: Ermöglicht das Ausführen eines Shell-Skripts in der Befehlszeile für jeden markierten Commit während des erneuten Abspielens.
Git-Zusammenfassung
Einer der Vorteile des interaktiven Rebasings besteht darin, dass Entwickler sich nicht um die Unordnung der Projektgeschichte sorgen müssen, da sie sie später bereinigen können. Daher verwenden viele Entwickler dieses Werkzeug, um die Historie des Feature-Branches sauberer zu machen, bevor sie ihn in den Master-Branch zusammenführen. Einen Branch zu bereinigen bedeutet, bedeutungslose oder längst überholte Commits zu entfernen. Dadurch erhalten Entwickler eine gut geplante Historie und können leicht nachvollziehen, welche Commits durchgeführt wurden.
Konfigurationsoptionen
Es gibt einige Rebase-Optionen, die mithilfe des Befehls git config gesetzt werden. Diese Optionen verändern das Verhalten und die Ausgabe von git rebase.
- rebase.stat: standardmäßig ein false-Boolean, der die Anzeige von visuellen Diffstat-Inhalten umschaltet, die Änderungen seit dem letzten Rebase zeigen.
- rebase.autoSquash: Ein boolescher Wert, der das Verhalten von
--autosquashumschaltet. - rebase.missingCommitsCheck: Kann auf mehrere Werte gesetzt werden, die das Rebase-Verhalten in Bezug auf fehlende Commits ändern. | warn | Warnausgabe wird im interaktiven Modus ausgegeben und warnt vor entfernten Commits. | |---|---| | error | Das Rebase wird gestoppt und Warnmeldungen zu entfernten Commits werden ausgegeben. | | ignore | Die Standardoption, die alle Warnungen zu fehlenden Commits ignoriert. |
- rebase.instructionFormat: Ein String im Format von git log, der für die Formatierung der Anzeige des interaktiven Rebase verwendet wird.
Erweiterte Rebase-Anwendung
An den git rebase kann das Befehlszeilenargument --onto übergeben werden, in welchem Fall der Befehl sich wie folgt erweitert:
git rebase --onto
git rebase --onto <newbase> <oldbase> <branch>Der --onto-Befehl ermöglicht eine erweiterte Rebase-Anwendung, da er das Übergeben bestimmter Refs als Rebase-Basis-Commits erlaubt.
Sehen wir uns sein Verhalten an einem Beispiel an:
git rebase --onto example
o---o---o---o---o master
\
o---o---o---o---o featureX
\
o---o---o featureYObwohl featureY ursprünglich auf featureX basierte, ist es unabhängig von den Änderungen von featureX und kann direkt auf master rebased werden. Dieser Befehl spielt die Commits von featureY auf master erneut ab und trennt featureY dadurch effektiv von featureX.
git rebase --onto command
git rebase --onto master featureX featureYFeatureX ist die <code><oldbase></code>, master ist die <code><newbase></code>, und featureY ist der Branch, der rebased wird. Hier ist die Ausgabe:
git rebase usage
o---o---o featureY
/
o---o---o---o---o master
\
o---o---o---o---o featureXDie Gefahren des Rebasings
Die erste Gefahr bei der Verwendung des git rebase-Befehls besteht darin, dass er während eines Rebase-Vorgangs zu mehr Merge-Konflikten führen kann, insbesondere in Fällen, in denen du einen langlebigen Branch hast, der sich von master abgespalten hat. Früher oder später entscheidest du dich möglicherweise, gegen den master zu rebasen, der einige neue Commits enthalten kann, mit denen die Änderungen deines Branches in Konflikt geraten. Die Lösung für die oben beschriebene Situation besteht darin, den Branch häufiger gegen master zu rebasen und häufiger Commits zu machen. Um das Rebase beim Auflösen von Konflikten fortzusetzen oder abzubrechen, kannst du die Argumente --continue und --abort mit git rebase verwenden. Ein weiteres, ernsteres Risiko besteht darin, dass einige Commits durch das Umschreiben der interaktiven Historie verloren gehen können. Das Ausführen von Rebase im interaktiven Modus mit einigen Unterbefehlen wie squash oder drop entfernt Commits aus dem unmittelbaren Log des Branches. Es kann so wirken, als wären die Commits dauerhaft entfernt. Die Lösung ist der git reflog, mit dem diese Commits wiederhergestellt werden können, und du kannst das gesamte Rebase rückgängig machen.
Wiederherstellung nach einem Rebase im Upstream
Falls ein anderer Benutzer einen Rebase durchgeführt und per Force-Push in den Branch gepusht hat, in den du committest, überschreibt ein git pull dann jeden Commit, der auf diesem vorherigen Branch basiert, mit der per Force-Push übertragenen Spitze. Git rebase ermöglicht dir die Verwendung des Reflogs des Remote-Branches. Dort kannst du einen Ref finden, bevor er rebased wurde. Dann kannst du deinen Branch mit der Option --onto gegen diesen Remote-Ref rebasen.
Practice
What are the correct statements about the `git rebase` command as described in the W3Docs Git Tutorial?