Ich möchte auf ein bestimmtes Commit zurückgreifen, nicht auf einen HEAD des anderen Zweigs:
A --- B --- C master
\
\-- D topic
zu
A --- B --- C master
\
\-- D topic
anstatt
A --- B --- C master
\
\-- D topic
Wie kann ich das erreichen?
git
version-control
rebase
git-rebase
Ondra Žižka
quelle
quelle
git checkout B
vor dem Laufen versuchtgit rebase
?rebase
Befehls sind wichtig.Antworten:
Sie können die Verwendung des Parameters --onto vermeiden, indem Sie einen temporären Zweig für das gewünschte Commit erstellen und dann rebase in seiner einfachen Form verwenden:
quelle
git rebase temp
(wenn auf Gruppe ) gibt mit "Aktuelle Zweiggruppen sind auf dem neuesten Stand." auf.git rebase --onto <target> <from> <to>
damit Sie das Commit <from> angeben können.Sie können sogar direkt vorgehen:
quelle
topic
und zu stützencommitB
.It works by going to the common ancestor of the two branches (the one you’re on and the one you’re rebasing onto), getting the diff introduced by each commit of the branch you’re on, saving those diffs to temporary files, resetting the current branch to the same commit as the branch you are rebasing onto, and finally applying each change in turn.
versuchte ich es jetzt noch einmal und schien gut zu funktionieren.m > n
.Verwenden Sie die Option "Ein":
quelle
D
undD^
wäre Hash des letzten und vorletzten Commits von "Thema"?git rebase --onto <new-parent> <old-parent>
. Siehe Setzen des übergeordneten Git-Zeigers auf ein anderes übergeordnetes Element . In Ihrem Fall ist <new-parent> B und <old-parent> A.git rebase --onto <commit-ID> master
git rebase --onto master <commit-ID-of-old-parent>
und für OPgit rebase --onto B A
.Der Kommentar von jsz oben hat mir jede Menge Schmerzen erspart. Hier ist ein Schritt-für-Schritt-Rezept, das darauf basiert und das ich verwendet habe, um ein Commit über ein anderes Commit zu verschieben / zu verschieben:
git rebase --onto <new parent> <old parent>
Im obigen Beispiel ist das so einfach wie:
quelle
git rebase --onto B master
finden Sie in meiner Antwort eine ausführlichere Erklärung.Themenlösung
Der richtige Befehl zur Beantwortung der gestellten Frage kann einer der folgenden sein (vorausgesetzt, der Zweig
topic
ist bereits ausgecheckt):Wenn
topic
nicht ausgecheckt, fügen Sie einfachtopic
den Befehl (mit Ausnahme des letzten) wie folgt hinzu :Alternativ können Sie zuerst die Filiale überprüfen mit:
Stellen Sie eine beliebige Zeichenfolge von Commits auf ein Ziel-Commit um
Die Grundform des Befehls, den wir benötigen und der aus der Dokumentation hervorgeht, lautet:
<Branch>
ist optional und überprüft lediglich den angegebenen Zweig, bevor der Rest des Befehls ausgeführt wird. Wenn Sie den Zweig, den Sie neu aufbauen möchten, bereits ausgecheckt haben, benötigen Sie diesen nicht. Beachten Sie, dass Sie angegeben haben müssen,<Upstream>
um anzugeben,<Branch>
oder git denkt, dass Sie angeben<Upstream>
.<Target>
ist das Commit, an das wir unsere Reihe von Commits anhängen werden. Wenn Sie einen Zweigstellennamen angeben, geben Sie einfach das Head Commit dieses Zweigs an.<Target>
kann ein beliebiges Commit sein, das nicht in der Zeichenfolge der zu verschiebenden Commits enthalten ist. Beispielsweise:Um den gesamten Funktionszweig zu verschieben, können Sie nicht wählen
X
,Y
,Z
oderfeature
wie die<Target>
da alle sind verpflichtet innerhalb der Gruppe bewegt werden.<Upstream>
ist etwas Besonderes, weil es zwei verschiedene Dinge bedeuten kann. Wenn es sich um ein Commit handelt, das ein Vorfahr des ausgecheckten Zweigs ist, dient es als Schnittpunkt. In dem Beispiel, das ich bereitgestellt habe, wäre dies alles, was nichtC
istD
, odermaster
. Alle Commits danach,<Upstream>
bis der Kopf des ausgecheckten Zweigs verschoben wird.Wenn
<Upstream>
es sich jedoch nicht um einen Vorfahren handelt, sichert git die Kette vom angegebenen Commit, bis ein gemeinsamer Vorfahr mit dem ausgecheckten Zweig gefunden wird (und bricht ab, wenn er keinen findet). In unserem Fall ein<Upstream>
vonB
,C
,D
odermaster
werden alle begehenB
als der Schnittpunkt dient.<Upstream>
ist selbst ein optionaler Befehl, und wenn er nicht angegeben ist, betrachtet git das übergeordnete Element des ausgecheckten Zweigs, was der Eingabe entsprichtmaster
.Nachdem git die Commits ausgewählt hat, die geschnitten und verschoben werden sollen, werden sie angewendet
<Target>
, um alle Commits zu überspringen, die bereits auf das Ziel angewendet wurden.Interessante Beispiele und Ergebnisse
Verwenden Sie diesen Ausgangspunkt:
git rebase --onto D A feature
Gelten Commits
B
,C
,X
,Y
,Z
zu begehenD
und das Überspringen am EndeB
undC
weil sie bereits angewendet wurden.git rebase --onto C X feature
Wendet Commits an
Y
undZ
legt festC
, wobei Commit effektiv gelöscht wirdX
quelle
Eine einfachere Lösung ist
git rebase <SHA1 of B> topic
. Dies funktioniert unabhängig davon, wo Sie sichHEAD
befinden.Wir können dieses Verhalten anhand des Git-Rebase-Dokuments bestätigen
Sie denken vielleicht, was passieren wird, wenn ich
topic
im obigen Befehl auch SHA1 erwähne ?git rebase <SHA1 of B> <SHA1 of topic>
Dies funktioniert auch, aber eine Neueinstellung macht dann keinen
Topic
Sinn für einen so erstellten neuen Zweig undHEAD
befindet sich im getrennten Zustand. Von hier aus müssen Sie also die alte manuell löschenTopic
und eine neue Zweigreferenz für einen neuen Zweig erstellen, der durch Rebase erstellt wurde.quelle
Ich habe eine Mischung der oben beschriebenen Lösungen verwendet:
Ich fand es viel einfacher zu lesen und zu verstehen. Die akzeptierte Lösung führte mich zu einem Zusammenführungskonflikt (zu faul, um von Hand behoben zu werden):
quelle
Da die Umbasierung so grundlegend ist, wird hier die Antwort von Nestor Milyaev erweitert . Die Kombination der Kommentare von jsz und Simon South aus der Antwort von Adam Dymitruk ergibt diesen Befehl, der für den
topic
Zweig funktioniert, unabhängig davon, ob er vommaster
Commit des Zweigs abzweigtA
oderC
:Beachten Sie, dass das letzte Argument erforderlich ist (andernfalls wird Ihr Zweig zum Festschreiben zurückgespult
B
).Beispiele:
Der letzte Befehl ist also der, den ich normalerweise benutze.
quelle
Es gibt eine andere Möglichkeit, dies zu tun, oder wenn Sie zu mehr als nur einem Commit zurückkehren möchten.
Hier ist ein Beispiel, um zur
n
Anzahl der Commits zurückzukehren:Um dieser Frage willen kann dies auch getan werden:
Der Befehl funktioniert einwandfrei
git version 2.7.4
. Ich habe es auf keiner anderen Version getestet.quelle