Einrichtung und Konfiguration
Projekte holen und erstellen
Grundlegende Snapshots
Branching und Merging
Projekte teilen und aktualisieren
Inspektion und Vergleich
Patching
Debugging
Externe Systeme
Server-Administration
Anleitungen
- gitattributes
- Konventionen der Kommandozeile
- Tägliches Git
- Häufig gestellte Fragen (FAQ)
- Glossar
- Hooks
- gitignore
- gitmodules
- Revisionen
- Submodule
- Tutorial
- Workflows
- Alle Anleitungen...
Administration
Plumbing-Befehle
-
2.52.0
2025-11-17
- 2.50.1 → 2.51.2 keine Änderungen
-
2.50.0
2025-06-16
- 2.49.1 keine Änderungen
-
2.49.0
2025-03-14
- 2.46.2 → 2.48.2 keine Änderungen
-
2.46.1
2024-09-13
- 2.45.1 → 2.46.0 keine Änderungen
-
2.45.0
2024-04-29
- 2.44.1 → 2.44.4 keine Änderungen
-
2.44.0
2024-02-23
- 2.43.3 → 2.43.7 keine Änderungen
-
2.43.2
2024-02-13
-
2.43.1
2024-02-09
-
2.43.0
2023-11-20
- 2.42.2 → 2.42.4 keine Änderungen
-
2.42.1
2023-11-02
- 2.41.1 → 2.42.0 keine Änderungen
-
2.41.0
2023-06-01
- 2.40.1 → 2.40.4 keine Änderungen
-
2.40.0
2023-03-12
- 2.39.4 → 2.39.5 keine Änderungen
-
2.39.3
2023-04-17
- 2.39.1 → 2.39.2 keine Änderungen
-
2.39.0
2022-12-12
- 2.38.1 → 2.38.5 keine Änderungen
-
2.38.0
2022-10-02
- 2.37.3 → 2.37.7 keine Änderungen
-
2.37.2
2022-08-11
- 2.36.3 → 2.37.1 keine Änderungen
-
2.36.2
2022-06-23
- 2.35.1 → 2.36.1 keine Änderungen
-
2.35.0
2022-01-24
- 2.34.1 → 2.34.8 keine Änderungen
-
2.34.0
2021-11-15
- 2.33.2 → 2.33.8 keine Änderungen
-
2.33.1
2021-10-12
- 2.32.1 → 2.33.0 keine Änderungen
-
2.32.0
2021-06-06
- 2.31.1 → 2.31.8 keine Änderungen
-
2.31.0
2021-03-15
- 2.30.1 → 2.30.9 keine Änderungen
-
2.30.0
2020-12-27
- 2.29.1 → 2.29.3 keine Änderungen
-
2.29.0
2020-10-19
- 2.28.1 keine Änderungen
-
2.28.0
2020-07-27
- 2.27.1 keine Änderungen
-
2.27.0
2020-06-01
- 2.26.1 → 2.26.3 keine Änderungen
-
2.26.0
2020-03-22
- 2.25.1 → 2.25.5 keine Änderungen
-
2.25.0
2020-01-13
- 2.24.1 → 2.24.4 keine Änderungen
-
2.24.0
2019-11-04
- 2.23.1 → 2.23.4 keine Änderungen
-
2.23.0
2019-08-16
- 2.22.1 → 2.22.5 keine Änderungen
-
2.22.0
2019-06-07
- 2.21.1 → 2.21.4 keine Änderungen
-
2.21.0
2019-02-24
- 2.20.1 → 2.20.5 keine Änderungen
-
2.20.0
2018-12-09
- 2.19.3 → 2.19.6 keine Änderungen
-
2.19.2
2018-11-21
- 2.19.1 keine Änderungen
-
2.19.0
2018-09-10
- 2.18.1 → 2.18.5 keine Änderungen
-
2.18.0
2018-06-21
- 2.17.1 → 2.17.6 keine Änderungen
-
2.17.0
2018-04-02
-
2.16.6
2019-12-06
-
2.15.4
2019-12-06
-
2.14.6
2019-12-06
-
2.13.7
2018-05-22
-
2.12.5
2017-09-22
- 2.10.5 → 2.11.4 keine Änderungen
-
2.9.5
2017-07-30
-
2.8.6
2017-07-30
- 2.7.6 keine Änderungen
-
2.6.7
2017-05-05
- 2.5.6 keine Änderungen
-
2.4.12
2017-05-05
-
2.3.10
2015-09-28
-
2.2.3
2015-09-04
-
2.1.4
2014-12-17
-
2.0.5
2014-12-17
SYNOPSIS
git rebase [-i | --interactive] [<options>] [--exec <cmd>] [--onto <newbase> | --keep-base] [<upstream> [<branch>]] git rebase [-i | --interactive] [<options>] [--exec <cmd>] [--onto <newbase>] --root [<branch>] git rebase (--continue|--skip|--abort|--quit|--edit-todo|--show-current-patch)
BESCHREIBUNG
Pflanzen Sie eine Serie von Commits auf einen anderen Startpunkt um. Sie können auch git rebase verwenden, um Commits neu zu ordnen oder zu kombinieren: siehe INTERAKTIVER MODUS unten, wie das geht.
Stellen Sie sich zum Beispiel vor, Sie hätten an dem topic-Branch in dieser Historie gearbeitet, und Sie möchten den auf dem master-Branch gemachten Arbeiten "aufholen".
A---B---C topic
/
D---E---F---G master
Sie möchten die Commits, die Sie auf topic gemacht haben, seitdem er von master abgewichen ist (d.h. A, B und C), auf den aktuellen master umpflanzen. Dies können Sie erreichen, indem Sie git rebase master ausführen, während der topic-Branch ausgecheckt ist. Wenn Sie topic umbasen möchten, während Sie sich auf einem anderen Branch befinden, ist git rebase master topic eine Abkürzung für git checkout topic && git rebase master.
A'--B'--C' topic
/
D---E---F---G master
Wenn während dieses Prozesses ein Merge-Konflikt auftritt, stoppt git rebase beim ersten problematischen Commit und hinterlässt Konfliktmarker. Wenn dies geschieht, können Sie eine der folgenden Aktionen durchführen:
-
Beheben Sie den Konflikt. Sie können
gitdiffverwenden, um die Marker (<<<<<<) zu finden und die Datei zur Behebung des Konflikts zu bearbeiten. Für jede bearbeitete Datei müssen Sie Git mitteilen, dass der Konflikt behoben wurde. Sie können den Konflikt mitgitadd<dateiname> als behoben markieren. Nachdem alle Konflikte behoben sind, können Sie den Rebase-Prozess fortsetzen mitgit rebase --continue
-
Brechen Sie den
gitrebaseab und setzen Sie Ihren Branch mit folgendem Befehl in seinen ursprünglichen Zustand zurück:git rebase --abort
-
Überspringen Sie den Commit, der den Merge-Konflikt verursacht hat, mit
git rebase --skip
Wenn Sie keinen <upstream> angeben, auf den rebased werden soll, werden die in den Optionen branch.<name>.remote und branch.<name>.merge konfigurierten Upstreams verwendet (siehe git-config[1] für Details), und die Option --fork-point wird angenommen. Wenn Sie sich derzeit auf keinem Branch befinden oder der aktuelle Branch keinen konfigurierten Upstream hat, wird der Rebase abgebrochen.
Hier ist eine vereinfachte Beschreibung dessen, was git rebase <upstream> tut:
-
Erstellen Sie eine Liste aller Commits auf Ihrem aktuellen Branch seitdem er von <upstream> abzweigte, die keinen entsprechenden Commit in <upstream> haben.
-
Checken Sie <upstream> mit dem Äquivalent von
gitcheckout--detach<upstream> aus. -
Spielen Sie die Commits nacheinander in der richtigen Reihenfolge ab. Dies ähnelt dem Ausführen von
gitcherry-pick<commit> für jeden Commit. Siehe MERGES REBASEN, wie Merges behandelt werden. -
Aktualisieren Sie Ihren Branch so, dass er auf den letzten Commit zeigt, mit dem Äquivalent von
gitcheckout-B<branch>.
|
Hinweis
|
Beim Start des Rebase wird ORIG_HEAD so gesetzt, dass er auf den Commit an der Spitze des zu rebasenden Branches zeigt. Allerdings ist nicht garantiert, dass ORIG_HEAD am Ende des Rebase immer noch auf diesen Commit zeigt, wenn andere Befehle, die ORIG_HEAD ändern (wie git reset), während des Rebase verwendet werden. Die vorherige Branch-Spitze ist jedoch über die Reflog des aktuellen Branches zugänglich (d.h. @{1}, siehe gitrevisions[7]. |
EINEN TOPIC-BRANCH MIT --ONTO UMPFLANZEN
Hier erfahren Sie, wie Sie einen Topic-Branch, der auf einem Branch basiert, auf einen anderen umpflanzen, um so zu tun, als hätten Sie den Topic-Branch von letzterem Branch verzweigt, mithilfe von rebase --onto.
Zuerst nehmen wir an, Ihr topic basiert auf dem Branch next. Zum Beispiel hängt ein in topic entwickelter Feature von Funktionalität ab, die in next zu finden ist.
o---o---o---o---o master
\
o---o---o---o---o next
\
o---o---o topic
Wir möchten, dass topic von master verzweigt wird; zum Beispiel, weil die Funktionalität, von der topic abhängt, in den stabileren master-Branch gemergt wurde. Wir möchten, dass unser Baum wie folgt aussieht:
o---o---o---o---o master
| \
| o'--o'--o' topic
\
o---o---o---o---o next
Dies können wir mit dem folgenden Befehl erreichen:
git rebase --onto master next topic
Ein weiteres Beispiel für die --onto-Option ist das Rebasen eines Teils eines Branches. Wenn wir folgende Situation haben:
H---I---J topicB
/
E---F---G topicA
/
A---B---C---D master
dann der Befehl
git rebase --onto master topicA topicB
würde dazu führen:
H'--I'--J' topicB
/
| E---F---G topicA
|/
A---B---C---D master
Dies ist nützlich, wenn topicB nicht von topicA abhängt.
Eine Reihe von Commits kann auch mit rebase entfernt werden. Wenn wir folgende Situation haben:
E---F---G---H---I---J topicA
dann der Befehl
git rebase --onto topicA~5 topicA~3 topicA
würde dazu führen, dass die Commits F und G entfernt werden.
E---H'---I'---J' topicA
Dies ist nützlich, wenn F und G fehlerhaft waren oder nicht Teil von topicA sein sollten. Beachten Sie, dass das Argument für --onto und der <upstream>-Parameter jedes gültige Commit-Objekt sein können.
MODUSOPTIONEN
Die Optionen in diesem Abschnitt können nicht mit anderen Optionen verwendet werden, auch nicht untereinander.
- --continue
-
Setzen Sie den Rebase-Prozess nach der Behebung eines Merge-Konflikts fort.
- --skip
-
Setzen Sie den Rebase-Prozess fort, indem Sie den aktuellen Patch überspringen.
- --abort
-
Brechen Sie die Rebase-Operation ab und setzen Sie HEAD auf den ursprünglichen Branch zurück. Wenn <branch> bei Beginn der Rebase-Operation angegeben wurde, wird
HEADauf <branch> zurückgesetzt. Andernfalls wirdHEADauf den Stand zurückgesetzt, auf dem es sich beim Beginn der Rebase-Operation befand. - --quit
-
Brechen Sie die Rebase-Operation ab, aber
HEADwird nicht auf den ursprünglichen Branch zurückgesetzt. Der Index und der Arbeitsbaum bleiben ebenfalls unverändert. Wenn ein temporärer Stash-Eintrag mit--autostasherstellt wurde, wird er in der Stash-Liste gespeichert. - --edit-todo
-
Bearbeiten Sie die Todo-Liste während eines interaktiven Rebase.
- --show-current-patch
-
Zeigen Sie den aktuellen Patch bei einem interaktiven Rebase an oder wenn der Rebase wegen Konflikten gestoppt wurde. Dies ist das Äquivalent zu
gitshowREBASE_HEAD.
OPTIONEN
- --onto <newbase>
-
Startpunkt, an dem die neuen Commits erstellt werden sollen. Wenn die Option
--ontonicht angegeben ist, ist der Startpunkt <upstream>. Kann jedes gültige Commit-Objekt sein, nicht nur ein bestehender Branch-Name.Als Sonderfall können Sie "A...B" als Abkürzung für die Merge-Basis von A und B verwenden, wenn es genau eine Merge-Basis gibt. Sie können höchstens eines von A oder B weglassen, in welchem Fall es standardmäßig HEAD ist.
Siehe EINEN TOPIC-BRANCH MIT --ONTO UMPFLANZEN oben für Beispiele.
- --keep-base
-
Setzen Sie den Startpunkt, an dem die neuen Commits erstellt werden sollen, auf die Merge-Basis von <upstream> und <branch>. Das Ausführen von
gitrebase--keep-base<upstream> <branch> ist äquivalent zum Ausführen vongitrebase--reapply-cherry-picks--no-fork-point--onto<upstream>...<branch> <upstream> <branch>.Diese Option ist nützlich, wenn man einen Feature-Entwicklung auf einem Upstream-Branch durchführt. Während der Arbeit am Feature kann sich der Upstream-Branch weiterentwickeln, und es ist möglicherweise nicht ratsam, immer weiter auf dem Upstream zu rebasen, sondern die Basis-Commits beizubehalten. Da die Basis-Commits unverändert bleiben, impliziert diese Option
--reapply-cherry-picks, um das Verlieren von Commits zu vermeiden.Obwohl sowohl diese Option als auch
--fork-pointdie Merge-Basis zwischen <upstream> und <branch> finden, verwendet diese Option die Merge-Basis als Startpunkt, auf dem neue Commits erstellt werden, während--fork-pointdie Merge-Basis verwendet, um die Menge der Commits zu bestimmen, die rebased werden.Siehe auch INKOMPATIBLE OPTIONEN unten.
- <upstream>
-
Upstream-Branch, mit dem verglichen werden soll. Kann jedes gültige Commit-Objekt sein, nicht nur ein bestehender Branch-Name. Standardmäßig der konfigurierte Upstream für den aktuellen Branch.
- <branch>
-
Arbeitsbranch; standardmäßig
HEAD. - --apply
-
Verwenden Sie Anwendungsstrategien zum Rebasen (Aufruf von
git-amintern). Diese Option kann in Zukunft eine No-op werden, sobald das Merge-Backend alles leistet, was das Apply-Backend tut.Siehe auch INKOMPATIBLE OPTIONEN unten.
- --empty=(drop|keep|stop)
-
Wie mit Commits umgegangen werden soll, die ursprünglich nicht leer waren und keine sauberen Cherry-Picks von Upstream-Commits sind, die aber nach dem Rebasen leer werden (da sie eine Teilmenge bereits vorhandener Upstream-Änderungen enthalten).
drop-
Der Commit wird verworfen. Dies ist das Standardverhalten.
keep-
Der Commit wird beibehalten. Diese Option wird impliziert, wenn
--execangegeben ist, es sei denn,-i/--interactiveist ebenfalls angegeben. stopask-
Der Rebase wird angehalten, wenn der Commit angewendet wird, was Ihnen die Wahl lässt, ob Sie ihn verwerfen, Dateien weiter bearbeiten oder einfach die leeren Änderungen committen möchten. Diese Option wird impliziert, wenn
-i/--interactiveangegeben ist.askist ein veraltetes Synonym fürstop.
Beachten Sie, dass Commits, die ursprünglich leer sind, beibehalten werden (es sei denn,
--no-keep-emptywird angegeben), und Commits, die saubere Cherry-Picks sind (wie vongitlog--cherry-mark... bestimmt), werden als vorbereitender Schritt erkannt und verworfen (es sei denn,--reapply-cherry-picksoder--keep-basewird übergeben).Siehe auch INKOMPATIBLE OPTIONEN unten.
- --no-keep-empty
- --keep-empty
-
Behalten Sie keine Commits, die vor dem Rebase leer sind (d.h. die nichts von ihrem Elternteil ändern), im Ergebnis. Standardmäßig werden Commits, die leer sind, beibehalten, da das Erstellen solcher Commits die Überschreibungsflagge
--allow-emptyangitcommiterfordert, was bedeutet, dass ein Benutzer einen solchen Commit sehr bewusst erstellt und ihn daher behalten möchte.Die Verwendung dieser Flagge wird wahrscheinlich selten vorkommen, da Sie Commits, die leer sind, einfach durch einen interaktiven Rebase loswerden können, indem Sie die Zeilen entfernen, die den Commits entsprechen, die Sie nicht möchten. Diese Flagge existiert als praktische Abkürzung, z.B. für Fälle, in denen externe Tools viele leere Commits generieren und Sie diese alle entfernen möchten.
Für Commits, die nicht leer sind, aber nach dem Rebasen leer werden, siehe die Option
--empty.Siehe auch INKOMPATIBLE OPTIONEN unten.
- --reapply-cherry-picks
- --no-reapply-cherry-picks
-
Wenden Sie alle sauberen Cherry-Picks von Upstream-Commits erneut an, anstatt sie präventiv zu verwerfen. (Wenn diese Commits nach dem Rebasen leer werden, weil sie eine Teilmenge von bereits vorhandenen Upstream-Änderungen enthalten, wird das Verhalten gegenüber ihnen durch die Option
--emptygesteuert.)In Abwesenheit von
--keep-base(oder wenn--no-reapply-cherry-picksangegeben wird) werden diese Commits automatisch verworfen. Da dies das Lesen aller Upstream-Commits erfordert, kann dies bei Repositories mit einer großen Anzahl von Upstream-Commits, die gelesen werden müssen, kostspielig sein. Bei Verwendung des merge-Backends werden Warnungen für jeden verworfenen Commit ausgegeben (es sei denn,--quietist angegeben). Ratschläge werden ebenfalls ausgegeben, es sei denn,advice.skippedCherryPicksist auf false gesetzt (siehe git-config[1]).--reapply-cherry-picksermöglicht es rebase, das Lesen aller Upstream-Commits zu vermeiden, was die Leistung potenziell verbessern kann.Siehe auch INKOMPATIBLE OPTIONEN unten.
- --allow-empty-message
-
No-op. Das Rebasen von Commits mit leerer Nachricht schlug früher fehl, und diese Option würde dieses Verhalten überschreiben und das Rebasen von Commits mit leerer Nachricht erlauben. Jetzt verursachen Commits mit leerer Nachricht nicht mehr, dass der Rebase stoppt.
Siehe auch INKOMPATIBLE OPTIONEN unten.
- -m
- --merge
-
Verwenden von Merge-Strategien zum Rebasen (Standard).
Beachten Sie, dass ein Rebase-Merge funktioniert, indem jeder Commit vom Arbeitsbranch auf den <upstream>-Branch wiederholt wird. Aus diesem Grund ist bei einem Merge-Konflikt die als ours berichtete Seite die bisher rebasete Serie, beginnend mit <upstream>, und theirs ist der Arbeitsbranch. Mit anderen Worten, die Seiten sind vertauscht.
Siehe auch INKOMPATIBLE OPTIONEN unten.
- -s <strategy>
- --strategy=<strategy>
-
Verwenden Sie die angegebene Merge-Strategie anstelle der Standard-Strategie
ort. Dies impliziert--merge.Da
gitrebasejeden Commit vom Arbeitsbranch auf den <upstream>-Branch unter Verwendung der angegebenen Strategie wiederholt, leert die Verwendung derours-Strategie einfach alle Patches aus dem <branch>, was wenig Sinn ergibt.Siehe auch INKOMPATIBLE OPTIONEN unten.
- -X <strategy-option>
- --strategy-option=<strategy-option>
-
Leiten Sie die <strategy-option> an die Merge-Strategie weiter. Dies impliziert
--mergeund, falls keine Strategie angegeben wurde,-sort. Beachten Sie die Vertauschung von ours und theirs, wie oben für die Option-merläutert.Siehe auch INKOMPATIBLE OPTIONEN unten.
--rerere-autoupdate--no-rerere-autoupdate-
Nachdem der rerere-Mechanismus eine aufgezeichnete Auflösung für den aktuellen Konflikt wiederverwendet hat, um die Dateien im Arbeitsbaum zu aktualisieren, erlauben Sie ihm auch, den Index mit dem Ergebnis der Auflösung zu aktualisieren.
--no-rerere-autoupdateist eine gute Möglichkeit, zu überprüfen, wasrereregetan hat, und potenzielle Fehlmerges zu erkennen, bevor das Ergebnis mit einem separatengitaddin den Index übernommen wird. - -S[<keyid>]
- --gpg-sign[=<keyid>]
- --no-gpg-sign
-
GPG-sign Commits. Das Argument
keyidist optional und standardmäßig die Committer-Identität; wenn es angegeben wird, muss es ohne Leerzeichen an die Option angehängt werden.--no-gpg-signist nützlich, um sowohl die Konfigurationsvariablecommit.gpgSignals auch einen früheren Befehl--gpg-signzu überschreiben. - -q
- --quiet
-
Seien Sie leise. Impliziert
--no-stat. - -v
- --verbose
-
Seien Sie ausführlich. Impliziert
--stat. - --stat
-
Zeigen Sie einen Diffstat an, der zeigt, was sich seit dem letzten Rebase beim Upstream geändert hat. Der Diffstat wird auch durch die Konfigurationsoption rebase.stat gesteuert.
- -n
- --no-stat
-
Zeigen Sie keinen Diffstat als Teil des Rebase-Prozesses an.
- --no-verify
-
Diese Option umgeht den Pre-Rebase-Hook. Siehe auch githooks[5].
- --verify
-
Erlaubt das Ausführen des Pre-Rebase-Hooks, was die Standardeinstellung ist. Diese Option kann verwendet werden, um
--no-verifyzu überschreiben. Siehe auch githooks[5]. - -C<n>
-
Stellen Sie sicher, dass mindestens <n> Zeilen umgebenden Kontext vor und nach jeder Änderung übereinstimmen. Wenn weniger Zeilen umgebenden Kontext vorhanden sind, müssen sie alle übereinstimmen. Standardmäßig wird nie Kontext ignoriert. Impliziert
--apply.Siehe auch INKOMPATIBLE OPTIONEN unten.
- --no-ff
- --force-rebase
- -f
-
Wenden Sie jeden neu basierenden Commit einzeln erneut an, anstatt unveränderte Commits per Fast-Forward zu überspringen. Dies stellt sicher, dass die gesamte Historie des neu basierenden Branches aus neuen Commits besteht.
Dies kann hilfreich sein, nachdem ein Merge eines Topic-Branches rückgängig gemacht wurde, da diese Option den Topic-Branch mit neuen Commits neu erstellt, damit er erfolgreich neu gemergt werden kann, ohne dass eine "Rückgängigmachung der Rückgängigmachung" erforderlich ist (siehe das How-To revert-a-faulty-merge für Details).
- --fork-point
- --no-fork-point
-
Verwenden Sie das Reflog, um einen besseren gemeinsamen Vorfahren zwischen <upstream> und <branch> zu finden, wenn Sie berechnen, welche Commits von <branch> eingeführt wurden.
Wenn
--fork-pointaktiv ist, wird fork_point anstelle von <upstream> verwendet, um die Menge der zu rebasenden Commits zu berechnen, wobei fork_point das Ergebnis des Befehlsgitmerge-base--fork-point<upstream> <branch> ist (siehe git-merge-base[1]). Wenn fork_point leer ist, wird <upstream> als Fallback verwendet.Wenn <upstream> oder
--keep-baseauf der Befehlszeile angegeben werden, ist die Standardeinstellung--no-fork-point, andernfalls ist die Standardeinstellung--fork-point. Siehe auchrebase.forkpointin git-config[1].Wenn Ihr Branch auf <upstream> basierte, aber <upstream> zurückgespult wurde und Ihr Branch Commits enthält, die verworfen wurden, kann diese Option mit
--keep-baseverwendet werden, um diese Commits aus Ihrem Branch zu entfernen.Siehe auch INKOMPATIBLE OPTIONEN unten.
- --ignore-whitespace
-
Ignorieren Sie Whitespace-Unterschiede beim Versuch, Unterschiede abzugleichen. Derzeit implementiert jedes Backend eine Annäherung dieses Verhaltens.
- apply backend
-
Beim Anwenden eines Patches ignorieren Sie Änderungen im Whitespace in Kontextzeilen. Unglücklicherweise bedeutet dies, dass, wenn die "alten" Zeilen, die durch den Patch ersetzt werden, sich nur im Whitespace vom bestehenden Dateiinhalt unterscheiden, Sie einen Merge-Konflikt anstelle einer erfolgreichen Patch-Anwendung erhalten.
- merge backend
-
Behandeln Sie Zeilen mit reinen Whitespace-Änderungen als unverändert beim Mergen. Unglücklicherweise bedeutet dies, dass alle Patch-Hunks, die nur Whitespace ändern sollten und nichts anderes, verworfen werden, selbst wenn die andere Seite keine Änderungen hatte, die kollidierten.
- --whitespace=<option>
-
Dieses Flag wird an das Programm
gitapply(siehe git-apply[1]) übergeben, das den Patch anwendet. Impliziert--apply.Siehe auch INKOMPATIBLE OPTIONEN unten.
- --committer-date-is-author-date
-
Anstatt die aktuelle Zeit als Committer-Datum zu verwenden, verwenden Sie das Autor-Datum des neu basierenden Commits als Committer-Datum. Diese Option impliziert
--force-rebase. - --ignore-date
- --reset-author-date
-
Anstatt das Autor-Datum des ursprünglichen Commits zu verwenden, verwenden Sie die aktuelle Zeit als Autor-Datum des neu basierenden Commits. Diese Option impliziert
--force-rebase.Siehe auch INKOMPATIBLE OPTIONEN unten.
- --signoff
-
Fügen Sie einen
Signed-off-byTrailer zu allen neu basierenden Commits hinzu. Beachten Sie, dass, wenn--interactiveangegeben ist, nur Commits, die zum Aufnehmen, Bearbeiten oder Umformulieren markiert sind, den Trailer erhalten.Siehe auch INKOMPATIBLE OPTIONEN unten.
- -i
- --interactive
-
Erstellen Sie eine Liste der Commits, die gerade rebased werden. Lassen Sie den Benutzer diese Liste bearbeiten, bevor Sie mit dem Rebase fortfahren. Dieser Modus kann auch zum Aufteilen von Commits verwendet werden (siehe COMMITS AUFTEILEN unten).
Das Format der Commit-Liste kann durch Setzen der Konfigurationsoption rebase.instructionFormat geändert werden. Ein angepasstes Instruktionsformat erhält automatisch den Commit-Hash am Anfang des Formats.
Siehe auch INKOMPATIBLE OPTIONEN unten.
- -r
- --rebase-merges[=(rebase-cousins|no-rebase-cousins)]
- --no-rebase-merges
-
Standardmäßig wird bei einem Rebase einfach die Merge-Commits aus der Todo-Liste gelöscht und die neu basierenden Commits in einem einzigen, linearen Branch abgelegt. Mit
--rebase-mergesversucht der Rebase stattdessen, die Verzweigungsstruktur innerhalb der zu rebasenden Commits zu erhalten, indem die Merge-Commits neu erstellt werden. Alle aufgetretenen Merge-Konflikte oder manuellen Änderungen in diesen Merge-Commits müssen manuell behoben/wieder angewendet werden.--no-rebase-mergeskann verwendet werden, um sowohl die Konfigurationsoptionrebase.rebaseMergesals auch eine vorherige Option--rebase-mergeszu überschreiben.Beim Rebasen von Merges gibt es zwei Modi:
rebase-cousinsundno-rebase-cousins. Wenn der Modus nicht angegeben ist, ist die Standardeinstellungno-rebase-cousins. Im Modusno-rebase-cousinsbehalten Commits, die nicht <upstream> als direkten Vorfahren haben, ihren ursprünglichen Verzweigungspunkt, d.h. Commits, die vongitlog[1]'s Option--ancestry-pathausgeschlossen würden, behalten standardmäßig ihre ursprüngliche Abstammung. Im Modusrebase-cousinswerden solche Commits stattdessen auf <upstream> (oder <onto>, falls angegeben) rebased.Es ist derzeit nur möglich, die Merge-Commits mit der Merge-Strategie
ortneu zu erstellen; verschiedene Merge-Strategien können nur über explizite Befehleexecgitmerge-s<strategy> [...] verwendet werden.Siehe auch MERGES REBASEN und INKOMPATIBLE OPTIONEN unten.
- -x <cmd>
- --exec <cmd>
-
Hängen Sie "exec <cmd>" nach jeder Zeile an, die einen Commit in der endgültigen Historie erstellt. <cmd> wird als ein oder mehrere Shell-Befehle interpretiert. Jeder Befehl, der fehlschlägt, unterbricht den Rebase mit dem Exit-Code 1.
Sie können mehrere Befehle ausführen, entweder mit einer Instanz von
--execmit mehreren Befehlen:git rebase -i --exec "cmd1 && cmd2 && ..."
oder durch Angabe von mehr als einem
--exec:git rebase -i --exec "cmd1" --exec "cmd2" --exec ...
Wenn
--autosquashverwendet wird, werdenexec-Zeilen nicht für die Zwischen-Commits angehängt und erscheinen nur am Ende jeder Squash/Fixup-Serie.Dies verwendet die interne Maschinerie von
--interactive, kann aber auch ohne explizites--interactiveausgeführt werden.Siehe auch INKOMPATIBLE OPTIONEN unten.
- --root
-
Rebasen Sie alle Commits, die von <branch> erreichbar sind, anstatt sie mit einem <upstream> zu begrenzen. Dies ermöglicht es Ihnen, den Wurzel-Commit (die Wurzel-Commits) eines Branches zu rebasen.
Siehe auch INKOMPATIBLE OPTIONEN unten.
- --autosquash
- --no-autosquash
-
Automatisch Commits mit speziell formatierten Nachrichten in vorherige Commits, die gerade rebased werden, einfügen. Wenn eine Commit-Nachricht mit "squash! ", "fixup! " oder "amend! " beginnt, wird der Rest des Titels als Commit-Spezifizierer verwendet, der mit einem vorherigen Commit übereinstimmt, wenn er dem Titel oder dem Hash dieses Commits entspricht. Wenn kein Commit vollständig übereinstimmt, werden Übereinstimmungen des Spezifizierers mit dem Anfang von Commit-Titeln berücksichtigt.
In der Rebase-Todo-Liste werden die Aktionen von Squash-, Fixup- und Amend-Commits von
pickzusquash,fixupoderfixup-Cgeändert und sie werden direkt nach dem Commit verschoben, den sie modifizieren. Die Option--interactivekann verwendet werden, um die Todo-Liste vor dem Fortfahren zu überprüfen und zu bearbeiten.Die empfohlene Methode zur Erstellung von Commits mit Squash-Markern ist die Verwendung der Optionen
--squash,--fixup,--fixup=amend:oder--fixup=reword:von git-commit[1], die das Ziel-Commit als Argument nehmen und den Titel des neuen Commits automatisch daraus füllen.Das Setzen der Konfigurationsvariable
rebase.autoSquashauf true aktiviert Auto-Squash standardmäßig für interaktive Rebase. Die Option--no-autosquashkann verwendet werden, um diese Einstellung zu überschreiben.Siehe auch INKOMPATIBLE OPTIONEN unten.
- --autostash
- --no-autostash
-
Erstellen Sie automatisch einen temporären Stash-Eintrag, bevor die Operation beginnt, und wenden Sie ihn nach Abschluss der Operation an. Das bedeutet, dass Sie Rebase auf einem schmutzigen Arbeitsbaum ausführen können. Verwenden Sie dies jedoch mit Vorsicht: die endgültige Stash-Anwendung nach einem erfolgreichen Rebase kann zu nicht-trivialen Konflikten führen.
- --reschedule-failed-exec
- --no-reschedule-failed-exec
-
Planen Sie
exec-Befehle, die fehlgeschlagen sind, automatisch neu. Dies ist nur im interaktiven Modus sinnvoll (oder wenn eine--exec-Option angegeben wurde).Diese Option wird angewendet, sobald ein Rebase gestartet wurde. Sie wird für den gesamten Rebase beibehalten, basierend auf, in Reihenfolge, der auf der Befehlszeile für den anfänglichen
gitrebaseangegebenen Option, der Konfigurationrebase.rescheduleFailedExec(siehe git-config[1] oder "KONFIGURATION" unten), oder standardmäßig auf false gesetzt.Das Aufzeichnen dieser Option für den gesamten Rebase ist eine Komfortfunktion. Andernfalls würde ein explizites
--no-reschedule-failed-execam Anfang durch die Anwesenheit einer Konfigurationrebase.rescheduleFailedExec=trueüberschrieben werden, wenngitrebase--continueaufgerufen wird. Derzeit können Sie--[no-]reschedule-failed-execnicht angitrebase--continueübergeben. - --update-refs
- --no-update-refs
-
Aktualisieren Sie automatisch alle Branches, die auf neu basierende Commits zeigen, mit einem Force-Update. Alle Branches, die in einem Worktree ausgecheckt sind, werden auf diese Weise nicht aktualisiert.
Wenn die Konfigurationsvariable
rebase.updateRefsgesetzt ist, kann diese Option verwendet werden, um diese Einstellung zu überschreiben und zu deaktivieren.Siehe auch INKOMPATIBLE OPTIONEN unten.
INKOMPATIBLE OPTIONEN
Die folgenden Optionen
-
--apply
-
--whitespace
-
-C
sind inkompatibel mit den folgenden Optionen
-
--merge
-
--strategy
-
--strategy-option
-
--autosquash
-
--rebase-merges
-
--interactive
-
--exec
-
--no-keep-empty
-
--empty=
-
--[no-]reapply-cherry-picks, wenn ohne --keep-base verwendet
-
--update-refs
-
--root, wenn ohne --onto verwendet
Zusätzlich sind die folgenden Optionenpaare inkompatibel:
-
--keep-base und --onto
-
--keep-base und --root
-
--fork-point und --root
VERHALTENSUNTERSCHIEDE
git rebase hat zwei Haupt-Backends: apply und merge. (Das apply-Backend war früher als am-Backend bekannt, aber der Name führte zu Verwirrung, da er wie ein Verb und nicht wie ein Nomen klingt. Auch das merge-Backend war früher als interaktives Backend bekannt, wird aber jetzt auch für nicht-interaktive Fälle verwendet. Beide wurden basierend auf den zugrunde liegenden Funktionalitäten, die jedem zugrunde liegen, umbenannt.) Es gibt einige subtile Unterschiede in der Funktionsweise dieser beiden Backends.
Leere Commits
Das apply-Backend verwirft leider absichtlich leere Commits, d.h. Commits, die ursprünglich leer waren, obwohl diese in der Praxis selten vorkommen. Es verwirft auch Commits, die leer werden, und es gibt keine Option, dieses Verhalten zu steuern.
Das merge-Backend behält absichtlich leere Commits standardmäßig bei (obwohl sie mit -i in der Todo-Listen-Editor als leer markiert werden oder automatisch mit --no-keep-empty verworfen werden können).
Ähnlich wie das apply-Backend verwirft das merge-Backend standardmäßig Commits, die leer werden, es sei denn, -i/--interactive wird angegeben (in diesem Fall stoppt es und fragt den Benutzer, was zu tun ist). Das merge-Backend hat auch eine Option --empty=(drop|keep|stop), um das Verhalten beim Umgang mit Commits, die leer werden, zu ändern.
Verzeichnissumbenennungserkennung
Aufgrund des Mangels an genauen Baum-Informationen (die sich aus der Erstellung gefälschter Vorfahren mit den begrenzten Informationen ergeben, die in Patches verfügbar sind), ist die Verzeichnissumbenennungserkennung im apply-Backend deaktiviert. Deaktivierte Verzeichnissumbenennungserkennung bedeutet, dass, wenn eine Seite der Historie ein Verzeichnis umbenennt und die andere neue Dateien in das alte Verzeichnis hinzufügt, die neuen Dateien im alten Verzeichnis zurückbleiben, ohne dass während des Rebasings eine Warnung ausgegeben wird, dass Sie diese Dateien möglicherweise in das neue Verzeichnis verschieben möchten.
Die Verzeichnissumbenennungserkennung funktioniert mit dem merge-Backend, um Sie in solchen Fällen zu warnen.
Kontext
Das apply-Backend erstellt eine Sequenz von Patches (durch internen Aufruf von format-patch) und wendet dann die Patches in Sequenz an (interner Aufruf von am). Patches bestehen aus mehreren "Hunks", die jeweils Zeilennummern, einen Kontextbereich und die eigentlichen Änderungen enthalten. Die Zeilennummern müssen mit einem gewissen Offset betrachtet werden, da die andere Seite wahrscheinlich früher in der Datei Zeilen eingefügt oder gelöscht hat. Der Kontextbereich dient dazu, die Zeilennummern anzupassen, um die Änderungen an den richtigen Zeilen anzuwenden. Wenn jedoch mehrere Bereiche des Codes die gleichen umliegenden Zeilen als Kontext haben, kann der falsche ausgewählt werden. Es gibt reale Fälle, in denen dies dazu geführt hat, dass Commits falsch neu angewendet wurden, ohne dass Konflikte gemeldet wurden. Das Setzen von diff.context auf einen größeren Wert kann solche Probleme verhindern, erhöht aber die Wahrscheinlichkeit von Scheinkonflikten (da mehr übereinstimmende Kontextzeilen zum Anwenden erforderlich sind).
Das merge-Backend arbeitet mit einer vollständigen Kopie jeder relevanten Datei und schützt es so vor diesen Arten von Problemen.
Beschriftung von Konfliktmarkern
Bei Inhaltskonflikten versucht die Merge-Maschinerie, die Konfliktmarker jeder Seite mit den Commits zu annotieren, aus denen der Inhalt stammt. Da das apply-Backend die ursprünglichen Informationen über die neu angewendeten Commits und ihre Eltern verwirft (und stattdessen neue gefälschte Commits basierend auf begrenzten Informationen in den generierten Patches erstellt), können diese Commits nicht identifiziert werden; stattdessen muss es auf eine Commit-Zusammenfassung zurückgreifen. Auch wenn merge.conflictStyle auf diff3 oder zdiff3 gesetzt ist, verwendet das apply-Backend eine "konstruierte Merge-Basis", um den Inhalt von der Merge-Basis zu beschriften, und liefert somit keine Informationen über den Merge-Basis-Commit.
Das merge-Backend arbeitet mit den vollständigen Commits auf beiden Seiten der Historie und hat daher keine solchen Einschränkungen.
Hooks
Das apply-Backend ruft traditionell nicht den Post-Commit-Hook auf, während das merge-Backend dies tut. Beide rufen den Post-Checkout-Hook auf, obwohl das merge-Backend seine Ausgabe unterdrückt. Darüber hinaus rufen beide Backends den Post-Checkout-Hook nur mit dem Start-Commit des Rebase auf, nicht mit den Zwischen-Commits oder dem End-Commit. In jedem Fall war das Aufrufen dieser Hooks ein Zufall der Implementierung und nicht des Designs (beide Backends wurden ursprünglich als Shell-Skripte implementiert und riefen zufällig andere Befehle wie git checkout oder git commit auf, die die Hooks aufrufen würden). Beide Backends sollten das gleiche Verhalten aufweisen, obwohl nicht ganz klar ist, welches, wenn überhaupt, korrekt ist. Wir werden wahrscheinlich dafür sorgen, dass rebase das Aufrufen dieser Hooks in Zukunft einstellt.
Unterbrechbarkeit
Das apply-Backend hat Sicherheitsprobleme bei einer ungünstig getimten Unterbrechung; wenn der Benutzer zur falschen Zeit Strg+C drückt, um den Rebase abzubrechen, kann der Rebase in einen Zustand geraten, in dem er mit einem nachfolgenden git rebase --abort nicht abgebrochen werden kann. Das merge-Backend scheint nicht unter demselben Mangel zu leiden. (Siehe https://lore.kernel.org/git/20200207132152.GC2868@szeder.dev/ für Details.)
Commit-Umbenennung
Wenn während des Rebasings ein Konflikt auftritt, stoppt rebase und bittet den Benutzer, ihn zu lösen. Da der Benutzer möglicherweise bemerkenswerte Änderungen vornehmen muss, während er Konflikte löst, sollte der Rebase nach dem Lösen der Konflikte und dem Ausführen von git rebase --continue durch den Benutzer einen Editor öffnen und den Benutzer bitten, die Commit-Nachricht zu aktualisieren. Das merge-Backend tut dies, während das apply-Backend blind die ursprüngliche Commit-Nachricht anwendet.
Sonstige Unterschiede
Es gibt einige weitere Verhaltensunterschiede, die die meisten Leute wahrscheinlich für unerheblich halten würden, die aber der Vollständigkeit halber erwähnt werden.
-
Reflog: Die beiden Backends verwenden unterschiedliche Formulierungen, wenn sie die im Reflog vorgenommenen Änderungen beschreiben, obwohl beide das Wort "rebase" verwenden.
-
Fortschritts-, Informations- und Fehlermeldungen: Die beiden Backends liefern leicht unterschiedliche Fortschritts- und Informationsmeldungen. Außerdem schreibt das apply-Backend Fehlermeldungen (wie "Ihre Dateien würden überschrieben ...") nach stdout, während das merge-Backend sie nach stderr schreibt.
-
Statusverzeichnisse: Die beiden Backends speichern ihren Status in verschiedenen Verzeichnissen unter
.git/.
MERGE-STRATEGIEN
Der Merge-Mechanismus (git merge und git pull Befehle) erlaubt die Auswahl der Backend-Merge-Strategien mit der Option -s. Einige Strategien können auch ihre eigenen Optionen haben, die durch Angabe von -X<option>-Argumenten an git merge und/oder git pull übergeben werden können.
ort-
Dies ist die Standard-Merge-Strategie beim Ziehen oder Zusammenführen eines Branches. Diese Strategie kann nur zwei Heads mit einem 3-Wege-Merge-Algorithmus auflösen. Wenn es mehr als einen gemeinsamen Vorfahren gibt, der für einen 3-Wege-Merge verwendet werden kann, erstellt sie einen zusammengeführten Baum der gemeinsamen Vorfahren und verwendet diesen als Referenzbaum für den 3-Wege-Merge. Dies führt Berichten zufolge zu weniger Merge-Konflikten, ohne Fehlmerges zu verursachen, wie Tests mit tatsächlichen Merge-Commits aus der Linux 2.6 Kernel-Entwicklungshistorie zeigen. Zusätzlich kann diese Strategie das Erkennen und Behandeln von Merges mit Umbenennungen. Sie nutzt keine erkannten Kopien. Der Name für diesen Algorithmus ist ein Akronym ("Ostensibly Recursive’s Twin") und entstand aus der Tatsache, dass er als Ersatz für den vorherigen Standardalgorithmus,
recursive, geschrieben wurde.In Fällen, in denen der Pfad ein Submodul ist, wenn der auf einer Seite des Merges verwendete Submodul-Commit ein Nachfahre des auf der anderen Seite des Merges verwendeten Submodul-Commits ist, versucht Git, zum Nachfahren zu wechseln. Andernfalls behandelt Git diesen Fall als Konflikt und schlägt als Auflösung einen Submodul-Commit vor, der ein Nachfahre der konfligierenden ist, falls einer existiert.
Die
ort-Strategie kann die folgenden Optionen annehmenours-
Diese Option erzwingt die automatische Auflösung von konfligierenden Hunks, indem sie die Version von *unserer* Seite bevorzugt. Änderungen vom anderen Baum, die nicht mit unserer Seite kollidieren, werden im Merge-Ergebnis berücksichtigt. Bei einer Binärdatei werden die gesamten Inhalte von unserer Seite übernommen.
Dies sollte nicht mit der
ours-Merge-Strategie verwechselt werden, die nicht einmal den anderen Baum betrachtet. Sie verwirft alles, was der andere Baum enthält, und erklärt, dass *unser* Verlauf alles enthält, was darin passiert ist. theirs-
Dies ist das Gegenteil von
ours; beachte, dass es im Gegensatz zuourskeinetheirs-Merge-Strategie gibt, mit der man diese Merge-Option verwechseln könnte. ignore-space-changeignore-all-spaceignore-space-at-eolignore-cr-at-eol-
Behandelt Zeilen mit der angegebenen Art von Leerzeichenänderung als unverändert für den Zweck eines Drei-Wege-Merges. Leerzeichenänderungen, die mit anderen Änderungen an einer Zeile vermischt sind, werden nicht ignoriert. Siehe auch git-diff[1]
-b,-w,--ignore-space-at-eolund--ignore-cr-at-eol.-
Wenn die *ihre* Version nur Leerzeichenänderungen an einer Zeile einführt, wird *unsere* Version verwendet;
-
Wenn *unsere* Version Leerzeichenänderungen einführt, aber *ihre* Version eine wesentliche Änderung enthält, wird *ihre* Version verwendet;
-
Andernfalls wird der Merge wie gewohnt fortgesetzt.
-
renormalize-
Führt einen virtuellen Checkout und Check-in aller drei Stufen jeder Datei durch, die einen Drei-Wege-Merge benötigt. Diese Option ist für das Mergen von Branches mit unterschiedlichen Clean-Filtern oder End-of-Line-Normalisierungsregeln gedacht. Siehe "Merging branches with differing checkin/checkout attributes" in gitattributes[5] für Details.
no-renormalize-
Deaktiviert die Option
renormalize. Dies überschreibt die Konfigurationsvariablemerge.renormalize. find-renames[=<n>]-
Schaltet die Erkennung von Umbenennungen ein und setzt optional den Ähnlichkeitsschwellenwert. Dies ist die Standardeinstellung. Dies überschreibt die Konfigurationsvariable
merge.renames. Siehe auch git-diff[1]--find-renames. rename-threshold=<n>-
Veraltetes Synonym für
find-renames=<n>. no-renames-
Schaltet die Erkennung von Umbenennungen aus. Dies überschreibt die Konfigurationsvariable
merge.renames. Siehe auch git-diff[1]--no-renames. histogram-
Veraltetes Synonym für
diff-algorithm=histogram. patience-
Veraltetes Synonym für
diff-algorithm=patience. diff-algorithm=(histogram|minimal|myers|patience)-
Verwendet einen anderen Diff-Algorithmus beim Mergen, der helfen kann, Fehlmerges zu vermeiden, die aufgrund unwichtiger übereinstimmender Zeilen (wie Klammern aus unterschiedlichen Funktionen) auftreten. Siehe auch git-diff[1]
--diff-algorithm. Beachten Sie, dassortstandardmäßigdiff-algorithm=histogramverwendet, während normale Diffs derzeit standardmäßig auf die Konfigurationseinstellungdiff.algorithmzurückgreifen. subtree[=<path>]-
Diese Option ist eine fortgeschrittenere Form der Subtree-Strategie, bei der die Strategie eine Vermutung darüber anstellt, wie zwei Bäume verschoben werden müssen, um zueinander zu passen, wenn sie gemerged werden. Stattdessen wird der angegebene Pfad vorangestellt (oder vom Anfang entfernt), um die Form zweier Bäume anzupassen.
recursive-
Dies ist jetzt ein Synonym für
ort. Es war bis v2.49.0 eine alternative Implementierung, wurde aber in v2.50.0 aufortumgeleitet. Die frühere rekursive Strategie war die Standardstrategie zum Auflösen von zwei Heads von Git v0.99.9k bis v2.33.0. resolve-
Dies kann nur zwei Heads (d.h. den aktuellen Branch und einen anderen von Ihnen gezogenen Branch) mittels eines 3-Wege-Merge-Algorithmus auflösen. Es versucht, Kreuz-Merge-Mehrdeutigkeiten sorgfältig zu erkennen. Es behandelt keine Umbenennungen.
octopus-
Dies löst Fälle mit mehr als zwei Heads auf, weigert sich aber, einen komplexen Merge durchzuführen, der eine manuelle Auflösung erfordert. Er ist hauptsächlich dazu gedacht, Topic-Branch-Heads zu bündeln. Dies ist die Standard-Merge-Strategie beim Ziehen oder Zusammenführen von mehr als einem Branch.
ours-
Dies löst eine beliebige Anzahl von Heads auf, aber der resultierende Baum des Merges ist immer der des aktuellen Branch-Heads, wobei alle Änderungen von allen anderen Branches effektiv ignoriert werden. Er ist dazu gedacht, die alte Entwicklungsgeschichte von Seiten-Branches zu ersetzen. Beachten Sie, dass dies sich von der Option
-Xourszurort-Merge-Strategie unterscheidet. subtree-
Dies ist eine modifizierte
ort-Strategie. Beim Mergen der Bäume A und B wird, wenn B einem Subtree von A entspricht, B zuerst angepasst, um die Baumstruktur von A abzugleichen, anstatt die Bäume auf derselben Ebene zu lesen. Diese Anpassung wird auch auf den gemeinsamen Vorfahren-Baum angewendet.
Mit den Strategien, die 3-Wege-Merges verwenden (einschließlich der Standardstrategie ort), wird eine Änderung, die auf beiden Branches vorgenommen wurde, aber später auf einem der Branches rückgängig gemacht wurde, im zusammengeführten Ergebnis vorhanden sein; einige Leute finden dieses Verhalten verwirrend. Es tritt auf, weil nur die Heads und die Merge-Basis für die Durchführung eines Merges berücksichtigt werden, nicht die einzelnen Commits. Der Merge-Algorithmus betrachtet daher die rückgängig gemachte Änderung als keine Änderung und ersetzt sie stattdessen durch die geänderte Version.
HINWEISE
Sie sollten die Auswirkungen der Verwendung von git rebase auf ein gemeinsam genutztes Repository verstehen. Siehe auch RECOVERING FROM UPSTREAM REBASE unten.
Wenn der Rebase ausgeführt wird, wird zuerst ein pre-rebase Hook aufgerufen, falls vorhanden. Sie können diesen Hook verwenden, um Integritätsprüfungen durchzuführen und den Rebase abzulehnen, wenn er nicht angemessen ist. Bitte beachten Sie das Vorlagen-Skript pre-rebase für ein Beispiel.
Nach Abschluss ist <branch> der aktuelle Branch.
INTERAKTIVER MODUS
Interaktives Rebasen bedeutet, dass Sie die Möglichkeit haben, die neu angewendeten Commits zu bearbeiten. Sie können die Commits neu anordnen und entfernen (schlechte oder anderweitig unerwünschte Patches aussondern).
Der interaktive Modus ist für diesen Workflow gedacht
-
eine wunderbare Idee haben
-
am Code hacken
-
eine Serie zur Einreichung vorbereiten
-
einreichen
wobei Punkt 2. mehrere Instanzen von
a) reguläre Nutzung
-
etwas fertigstellen, das einen Commit wert ist
-
commit
b) unabhängige Korrektur
-
merken, dass etwas nicht funktioniert
-
das beheben
-
commit
Manchmal kann das in b.2. behobene Problem nicht an den nicht ganz perfekten Commit angehängt werden, den es behebt, weil dieser Commit tief in einer Patch-Serie vergraben ist. Genau dafür ist das interaktive Rebase gedacht: Verwenden Sie es nach vielen "a"s und "b"s, indem Sie Commits neu anordnen und bearbeiten und mehrere Commits zu einem zusammenfassen.
Starten Sie es mit dem letzten Commit, den Sie unverändert beibehalten möchten.
git rebase -i <after-this-commit>
Ein Editor wird mit allen Commits in Ihrem aktuellen Branch (unter Ignorierung von Merge-Commits) gestartet, die nach dem angegebenen Commit kommen. Sie können die Commits in dieser Liste nach Belieben neu anordnen und entfernen. Die Liste sieht mehr oder weniger so aus
pick deadbee The oneline of this commit pick fa1afe1 The oneline of the next commit ...
Die Einzeiler-Beschreibungen dienen nur Ihrer Freude; git rebase wird sie nicht ansehen, sondern die Commit-Namen ("deadbee" und "fa1afe1" in diesem Beispiel), also löschen oder bearbeiten Sie die Namen nicht.
Durch Ersetzen des Befehls "pick" durch den Befehl "edit" können Sie git rebase anweisen, nach dem Anwenden dieses Commits zu stoppen, damit Sie die Dateien und/oder die Commit-Nachricht bearbeiten, den Commit ändern und mit dem Rebasen fortfahren können.
Um den Rebase zu unterbrechen (genau wie bei einem "edit"-Befehl, aber ohne vorherige Übernahme eines Commits), verwenden Sie den Befehl "break".
Wenn Sie nur die Commit-Nachricht eines Commits bearbeiten möchten, ersetzen Sie den Befehl "pick" durch den Befehl "reword".
Um einen Commit zu verwerfen, ersetzen Sie den Befehl "pick" durch "drop" oder löschen Sie einfach die entsprechende Zeile.
Wenn Sie zwei oder mehr Commits zu einem zusammenführen möchten, ersetzen Sie den Befehl "pick" für den zweiten und nachfolgenden Commits durch "squash" oder "fixup". Wenn die Commits unterschiedliche Autoren hatten, wird der zusammengeführte Commit dem Autor des ersten Commits zugeschrieben. Die vorgeschlagene Commit-Nachricht für den zusammengeführten Commit ist die Verkettung der Nachricht des ersten Commits mit denen, die durch "squash"-Befehle identifiziert wurden, wobei die Nachrichten von durch "fixup"-Befehle identifizierten Commits weggelassen werden, es sei denn, "fixup -c" wird verwendet. In diesem Fall ist die vorgeschlagene Commit-Nachricht nur die Nachricht des "fixup -c"-Commits, und ein Editor wird geöffnet, der es Ihnen ermöglicht, die Nachricht zu bearbeiten. Der Inhalt (Patch) des "fixup -c"-Commits wird dennoch in den zusammengeführten Commit einbezogen. Wenn es mehr als einen "fixup -c"-Commit gibt, wird die Nachricht des letzten verwendet. Sie können auch "fixup -C" verwenden, um das gleiche Verhalten wie bei "fixup -c" zu erhalten, außer dass kein Editor geöffnet wird.
git rebase stoppt, wenn "pick" durch "edit" ersetzt wurde oder wenn ein Befehl aufgrund von Merge-Fehlern fehlschlägt. Wenn Sie mit der Bearbeitung und/oder dem Lösen von Konflikten fertig sind, können Sie mit git rebase --continue fortfahren.
Wenn Sie beispielsweise die letzten 5 Commits neu anordnen möchten, so dass HEAD~4 zum neuen HEAD wird. Um dies zu erreichen, würden Sie git rebase wie folgt aufrufen
$ git rebase -i HEAD~5
und den ersten Patch ans Ende der Liste verschieben.
Möglicherweise möchten Sie Merge-Commits neu erstellen, z. B. wenn Sie eine Historie wie diese haben
X
\
A---M---B
/
---o---O---P---Q
Angenommen, Sie möchten den Seiten-Branch, der bei "A" beginnt, auf "Q" rebasen. Stellen Sie sicher, dass der aktuelle HEAD "B" ist, und rufen Sie auf
$ git rebase -i -r --onto Q O
Das Neuordnen und Bearbeiten von Commits erzeugt normalerweise ungetestete Zwischenschritte. Möglicherweise möchten Sie überprüfen, ob Ihre Historienbearbeitung nichts kaputt gemacht hat, indem Sie einen Test durchführen oder zumindest an Zwischenpunkten der Historie neu kompilieren, indem Sie den Befehl "exec" (Abkürzung "x") verwenden. Dies können Sie tun, indem Sie eine Todo-Liste wie diese erstellen
pick deadbee Implement feature XXX fixup f1a5c00 Fix to feature XXX exec make pick c0ffeee The oneline of the next commit edit deadbab The oneline of the commit after exec cd subdir; make test ...
Das interaktive Rebase stoppt, wenn ein Befehl fehlschlägt (d. h. mit einem Nicht-0-Status beendet wird), um Ihnen die Möglichkeit zu geben, das Problem zu beheben. Sie können mit git rebase --continue fortfahren.
Der Befehl "exec" startet den Befehl in einer Shell (der Standard-Shell, normalerweise /bin/sh), sodass Sie Shell-Funktionen (wie "cd", ">", ";" …) verwenden können. Der Befehl wird vom Stamm des Arbeitsbaums aus ausgeführt.
$ git rebase -i --exec "make test"
Dieser Befehl ermöglicht es Ihnen zu überprüfen, ob Zwischen-Commits kompilierbar sind. Die Todo-Liste wird dann so aussehen
pick 5928aea one exec make test pick 04d0fda two exec make test pick ba46169 three exec make test pick f4593f9 four exec make test
COMMITS AUFTEILEN
Im interaktiven Modus können Sie Commits mit der Aktion "edit" markieren. Dies bedeutet jedoch nicht unbedingt, dass git rebase erwartet, dass das Ergebnis dieser Bearbeitung genau ein Commit ist. Tatsächlich können Sie den Commit rückgängig machen oder andere Commits hinzufügen. Dies kann verwendet werden, um einen Commit in zwei aufzuteilen.
-
Starten Sie einen interaktiven Rebase mit
gitrebase-i<commit>^, wobei <commit> der Commit ist, den Sie aufteilen möchten. Tatsächlich kann jeder Commit-Bereich ausreichen, solange er diesen Commit enthält. -
Markieren Sie den zu teilenden Commit mit der Aktion "edit".
-
Wenn es an der Zeit ist, diesen Commit zu bearbeiten, führen Sie
gitresetHEAD^aus. Dies bewirkt, dassHEADum eins zurückgesetzt wird und der Index diesem folgt. Der Arbeitsbaum bleibt jedoch unverändert. -
Fügen Sie nun die Änderungen zum Index hinzu, die Sie im ersten Commit haben möchten. Sie können dazu
gitadd(ggf. interaktiv) odergitgui(oder beides) verwenden. -
Comitten Sie den nun aktuellen Index mit der entsprechenden Commit-Nachricht.
-
Wiederholen Sie die letzten beiden Schritte, bis Ihr Arbeitsbaum sauber ist.
-
Fahren Sie mit dem Rebase mit
gitrebase--continuefort.
Wenn Sie sich nicht absolut sicher sind, dass die Zwischenrevisionen konsistent sind (sie kompilieren, bestehen den Test-Suite usw.), sollten Sie git stash verwenden, um die noch nicht committeten Änderungen nach jedem Commit wegzulegen, zu testen und den Commit zu ändern, wenn Korrekturen notwendig sind.
WIEDERHERSTELLUNG NACH UPSTREAM-REBASE
Das Rebasen (oder jede andere Form des Umschreibens) eines Branches, auf dem andere Arbeit aufgebaut haben, ist eine schlechte Idee: jeder nachfolgende Benutzer muss seine Historie manuell korrigieren. Dieser Abschnitt erklärt, wie die Korrektur aus der Sicht des nachfolgenden Benutzers vorgenommen wird. Die eigentliche Korrektur wäre jedoch, das Rebasen des Upstreams von vornherein zu vermeiden.
Zur Veranschaulichung nehmen wir an, Sie befinden sich in einer Situation, in der jemand einen Subsystem-Branch entwickelt und Sie an einem Thema arbeiten, das von diesem Subsystem abhängt. Möglicherweise haben Sie eine Historie wie die folgende
o---o---o---o---o---o---o---o master \ o---o---o---o---o subsystem \ *---*---* topic
Wenn subsystem gegen master neu angewendet wird, geschieht Folgendes
o---o---o---o---o---o---o---o master \ \ o---o---o---o---o o'--o'--o'--o'--o' subsystem \ *---*---* topic
Wenn Sie nun die Entwicklung wie gewohnt fortsetzen und schließlich topic in subsystem mergen, bleiben die Commits von subsystem für immer dupliziert.
o---o---o---o---o---o---o---o master \ \ o---o---o---o---o o'--o'--o'--o'--o'--M subsystem \ / *---*---*-..........-*--* topic
Solche Duplikate werden im Allgemeinen missbilligt, da sie die Historie unübersichtlich machen und das Nachvollziehen erschweren. Um aufzuräumen, müssen Sie die Commits auf topic auf die neue subsystem-Spitze übertragen, d. h. topic neu anwenden. Dies wird zu einem Welleneffekt: Jeder nachfolgende Benutzer von topic muss ebenfalls neu anwenden und so weiter!
Es gibt zwei Arten von Korrekturen, die in den folgenden Unterabschnitten behandelt werden.
- Einfacher Fall: Die Änderungen sind buchstäblich dieselben.
-
Dies geschieht, wenn das subsystem-Rebase ein einfaches Rebase war und keine Konflikte aufwies.
- Schwerer Fall: Die Änderungen sind nicht dieselben.
-
Dies geschieht, wenn das subsystem-Rebase Konflikte hatte oder
--interactiveverwendete, um Commits wegzulassen, zu bearbeiten, zusammenzufassen oder zu korrigieren; oder wenn der Upstream einen der Befehlecommit--amend,resetoder einen vollständigen Historien-Umschreibungsbefehl wiefilter-repoverwendete.
Der einfache Fall
Funktioniert nur, wenn die Änderungen (Patch-IDs basierend auf den Diff-Inhalten) in subsystem vor und nach dem Rebase des subsystem buchstäblich gleich sind.
In diesem Fall ist die Korrektur einfach, weil git rebase weiß, dass bereits vorhandene Änderungen im neuen Upstream übersprungen werden (es sei denn, --reapply-cherry-picks wird angegeben). Wenn Sie also sagen (vorausgesetzt, Sie befinden sich auf topic)
$ git rebase subsystem
erhalten Sie die korrigierte Historie.
o---o---o---o---o---o---o---o master \ o'--o'--o'--o'--o' subsystem \ *---*---* topic
Der schwere Fall
Die Dinge werden komplizierter, wenn die subsystem-Änderungen nicht exakt mit denen vor dem Rebase übereinstimmen.
|
Hinweis
|
Während eine "einfache Fall-Wiederherstellung" im schweren Fall manchmal erfolgreich zu sein scheint, kann sie unbeabsichtigte Folgen haben. Zum Beispiel wird ein Commit, der über git rebase --interactive entfernt wurde, **wiederbelebt**! |
Die Idee ist, git rebase manuell mitzuteilen, "wo das alte subsystem endete und Ihr topic begann", d.h. was die alte gemeinsame Basis zwischen ihnen war. Sie müssen einen Weg finden, die letzte Commit des alten subsystem zu benennen, zum Beispiel
-
Mit dem Reflog von subsystem: Nach
gitfetchbefindet sich die alte Spitze von subsystem beisubsystem@{1}. Nachfolgende Fetches erhöhen die Zahl. (Siehe git-reflog[1].) -
Relativ zur Spitze von topic: Wenn Sie wissen, dass Ihr topic drei Commits hat, muss die alte Spitze von subsystem
topic~3sein.
Sie können dann die alten subsystem..topic-Commits auf die neue Spitze übertragen, indem Sie sagen (für den Reflog-Fall, und vorausgesetzt, Sie sind bereits auf topic)
$ git rebase --onto subsystem subsystem@{1}
Der Welleneffekt einer "schweren Fall"-Wiederherstellung ist besonders schlimm: jeder nachfolgende Benutzer von topic muss ebenfalls eine "schwere Fall"-Wiederherstellung durchführen!
MERGES NEU ANWENDEN
Der interaktive Rebase-Befehl wurde ursprünglich für die Bearbeitung einzelner Patch-Serien entwickelt. Daher ist es sinnvoll, Merge-Commits aus der Todo-Liste auszuschließen, da der Entwickler möglicherweise den damaligen master gemerged hat, während er am Branch arbeitete, nur um später alle Commits auf master neu anzuwenden (und die Merge-Commits zu überspringen).
Es gibt jedoch legitime Gründe, warum ein Entwickler Merge-Commits neu erstellen möchte: um die Branch-Struktur (oder "Commit-Topologie") beizubehalten, wenn an mehreren, miteinander verbundenen Branches gearbeitet wird.
Im folgenden Beispiel arbeitet der Entwickler an einem Topic-Branch, der die Definition von Buttons refaktoriert, und an einem anderen Topic-Branch, der diese Refaktorisierung verwendet, um einen "Report a bug"-Button zu implementieren. Die Ausgabe von git log --graph --format=%s -5 könnte wie folgt aussehen
* Merge branch 'report-a-bug' |\ | * Add the feedback button * | Merge branch 'refactor-button' |\ \ | |/ | * Use the Button class for all buttons | * Extract a generic Button class from the DownloadButton one
Der Entwickler möchte diese Commits möglicherweise auf einen neueren master neu anwenden, während die Branch-Topologie beibehalten wird, zum Beispiel, wenn erwartet wird, dass der erste Topic-Branch viel früher als der zweite in master integriert wird, um Merge-Konflikte mit Änderungen an der Klasse DownloadButton zu lösen, die es in master geschafft haben.
Dieser Rebase kann mit der Option --rebase-merges durchgeführt werden. Er generiert eine Todo-Liste, die wie folgt aussieht
label onto # Branch: refactor-button reset onto pick 123456 Extract a generic Button class from the DownloadButton one pick 654321 Use the Button class for all buttons label refactor-button # Branch: report-a-bug reset refactor-button # Use the Button class for all buttons pick abcdef Add the feedback button label report-a-bug reset onto merge -C a1b2c3 refactor-button # Merge 'refactor-button' merge -C 6f5e4d report-a-bug # Merge 'report-a-bug'
Im Gegensatz zu einem regulären interaktiven Rebase gibt es neben den pick-Befehlen auch label-, reset- und merge-Befehle.
Der Befehl label ordnet der aktuellen HEAD ein Label zu, wenn dieser Befehl ausgeführt wird. Diese Labels werden als Worktree-lokale Refs (refs/rewritten/<label>) erstellt, die gelöscht werden, wenn der Rebase abgeschlossen ist. Auf diese Weise stören sich Rebase-Operationen in mehreren Worktrees, die mit demselben Repository verknüpft sind, nicht gegenseitig. Wenn der Befehl label fehlschlägt, wird er sofort neu geplant, mit einer hilfreichen Nachricht, wie fortzufahren ist.
Der Befehl reset setzt die HEAD, den Index und den Arbeitsbaum auf die angegebene Revision zurück. Er ist ähnlich wie ein exec git reset --hard <label>, weigert sich jedoch, nicht verfolgte Dateien zu überschreiben. Wenn der Befehl reset fehlschlägt, wird er sofort neu geplant, mit einer hilfreichen Nachricht, wie die Todo-Liste zu bearbeiten ist (dies geschieht typischerweise, wenn ein reset-Befehl manuell in die Todo-Liste eingefügt wurde und einen Tippfehler enthält).
Der Befehl merge wird die angegebene(n) Revision(en) mit dem jeweiligen HEAD mergen. Mit -C <original-commit> wird die Commit-Nachricht des angegebenen Merge-Commits verwendet. Wenn -C zu einem Kleinbuchstaben -c geändert wird, wird die Nachricht nach einem erfolgreichen Merge in einem Editor geöffnet, damit der Benutzer die Nachricht bearbeiten kann.
Wenn ein merge-Befehl aus anderen Gründen als Merge-Konflikten fehlschlägt (d. h. wenn die Merge-Operation nicht einmal begonnen hat), wird er sofort neu geplant.
Standardmäßig verwendet der Befehl merge die Merge-Strategie ort für reguläre Merges und octopus für Octopus-Merges. Man kann eine Standardstrategie für alle Merges über das Argument --strategy beim Aufrufen von rebase angeben, oder man kann spezifische Merges in der interaktiven Liste von Befehlen überschreiben, indem man einen exec-Befehl aufruft, um explizit git merge mit einem --strategy-Argument aufzurufen. Beachten Sie, dass Sie bei explizitem Aufruf von git merge die Tatsache nutzen können, dass die Labels Worktree-lokale Refs sind (die Ref refs/rewritten/onto würde beispielsweise dem Label onto entsprechen), um die zu mergenden Branches zu referenzieren.
Hinweis: Der erste Befehl (label onto) beschriftet die Revision, auf die die Commits neu angewendet werden; Der Name onto ist nur eine Konvention, als Anspielung auf die Option --onto.
Es ist auch möglich, völlig neue Merge-Commits von Grund auf neu zu erstellen, indem man einen Befehl der Form merge <merge-head> hinzufügt. Diese Form generiert eine vorläufige Commit-Nachricht und öffnet immer einen Editor, damit der Benutzer sie bearbeiten kann. Dies kann nützlich sein, z. B. wenn sich herausstellt, dass ein Topic-Branch mehr als ein einzelnes Anliegen betrifft und in zwei oder sogar mehr Topic-Branches aufgeteilt werden soll. Betrachten Sie diese Todo-Liste
pick 192837 Switch from GNU Makefiles to CMake pick 5a6c7e Document the switch to CMake pick 918273 Fix detection of OpenSSL in CMake pick afbecd http: add support for TLS v1.3 pick fdbaec Fix detection of cURL in CMake on Windows
Der eine Commit in dieser Liste, der nicht mit CMake zusammenhängt, wurde möglicherweise durch die Behebung all der Fehler motiviert, die durch die Umstellung auf CMake eingeführt wurden, befasst sich aber mit einem anderen Anliegen. Um diesen Branch in zwei Topic-Branches aufzuteilen, könnte die Todo-Liste wie folgt bearbeitet werden
label onto pick afbecd http: add support for TLS v1.3 label tlsv1.3 reset onto pick 192837 Switch from GNU Makefiles to CMake pick 918273 Fix detection of OpenSSL in CMake pick fdbaec Fix detection of cURL in CMake on Windows pick 5a6c7e Document the switch to CMake label cmake reset onto merge tlsv1.3 merge cmake
KONFIGURATION
Alles unterhalb dieser Zeile in diesem Abschnitt wird selektiv aus der git-config[1]-Dokumentation übernommen. Der Inhalt ist derselbe wie dort zu finden.
- rebase.backend
-
Standard-Backend, das für das Rebasen verwendet werden soll. Mögliche Optionen sind apply oder merge. In Zukunft, wenn das merge-Backend alle verbleibenden Fähigkeiten des apply-Backends erhält, wird diese Einstellung möglicherweise nicht mehr verwendet.
- rebase.stat
-
Ob eine Diff-Statistik dessen angezeigt werden soll, was sich seit dem letzten Rebase upstream geändert hat. Standardmäßig False.
- rebase.autoSquash
-
Wenn auf true gesetzt, wird die Option
--autosquashvon git-rebase[1] für den interaktiven Modus standardmäßig aktiviert. Dies kann mit der Option--no-autosquashüberschrieben werden. - rebase.autoStash
-
Wenn auf true gesetzt, wird vor dem Beginn der Operation automatisch ein temporärer Stash-Eintrag erstellt und nach Beendigung der Operation wieder angewendet. Das bedeutet, dass Sie rebase auf einem "dirty" Working Tree ausführen können. Verwenden Sie dies jedoch mit Vorsicht: Das endgültige Anwenden des Stash nach einem erfolgreichen Rebase kann zu nicht trivialen Konflikten führen. Diese Option kann durch die Optionen
--no-autostashund--autostashvon git-rebase[1] überschrieben werden. Standardmäßig false. - rebase.updateRefs
-
Wenn auf true gesetzt, wird die Option
--update-refsstandardmäßig aktiviert. - rebase.missingCommitsCheck
-
Wenn auf "warn" gesetzt, wird git rebase -i eine Warnung ausgeben, wenn einige Commits entfernt werden (z.B. wenn eine Zeile gelöscht wurde), der Rebase wird jedoch fortgesetzt. Wenn auf "error" gesetzt, wird die vorherige Warnung ausgegeben und der Rebase gestoppt. git rebase --edit-todo kann dann verwendet werden, um den Fehler zu korrigieren. Wenn auf "ignore" gesetzt, wird keine Prüfung durchgeführt. Um einen Commit ohne Warnung oder Fehler zu verwerfen, verwenden Sie den Befehl
dropin der To-do-Liste. Standardmäßig "ignore". - rebase.instructionFormat
-
Ein Formatstring, wie in git-log[1] spezifiziert, der für die To-do-Liste während eines interaktiven Rebase verwendet wird. Das Format wird automatisch mit dem Commit-Hash vorangestellt.
- rebase.abbreviateCommands
-
Wenn auf true gesetzt, verwendet
gitrebaseabgekürzte Befehlsnamen in der To-do-Liste, was zu etwas wie folgt führt:p deadbee The oneline of the commit p fa1afe1 The oneline of the next commit ...
anstatt
pick deadbee The oneline of the commit pick fa1afe1 The oneline of the next commit ...
Standardmäßig false.
- rebase.rescheduleFailedExec
-
Automatisch fehlgeschlagene
exec-Befehle neu planen. Dies ist nur im interaktiven Modus sinnvoll (oder wenn eine Option--execangegeben wurde). Dies entspricht der Angabe der Option--reschedule-failed-exec. - rebase.forkPoint
-
Wenn auf false gesetzt, wird die Option
--no-fork-pointstandardmäßig gesetzt. - rebase.rebaseMerges
-
Ob und wie die Option
--rebase-mergesstandardmäßig gesetzt wird. Kannrebase-cousins,no-rebase-cousinsoder ein boolescher Wert sein. Das Setzen auf true oderno-rebase-cousinsentspricht--rebase-merges=no-rebase-cousins, das Setzen aufrebase-cousinsentspricht--rebase-merges=rebase-cousinsund das Setzen auf false entspricht--no-rebase-merges. Das Übergeben von--rebase-mergesauf der Kommandozeile, mit oder ohne Argument, überschreibt jederebase.rebaseMergesKonfiguration. - rebase.maxLabelLength
-
Beim Generieren von Label-Namen aus Commit-Betreffzeilen werden die Namen auf diese Länge gekürzt. Standardmäßig werden die Namen auf etwas weniger als
NAME_MAXgekürzt (um z.B. das Schreiben von.lock-Dateien für die entsprechenden lose Referenzen zu ermöglichen). - sequence.editor
-
Texteditor, der von
gitrebase-izum Bearbeiten der Rebase-Instruktionsdatei verwendet wird. Der Wert ist für die Interpretation durch die Shell vorgesehen, wenn er verwendet wird. Er kann durch die UmgebungsvariableGIT_SEQUENCE_EDITORüberschrieben werden. Wenn nicht konfiguriert, wird stattdessen der Standard-Commit-Nachrichteneditor verwendet.
GIT
Teil der git[1] Suite