Zweigbasis ändern

144

Ich habe einen Baum wie diesen:

(commit 1) - master
                \-- (commit 2) - (commit 3) - demo
                                                \-- (commit 4) - (commit 5) - PRO

und ich muss den PRO-Zweig zum Master verschieben

(commit 1) - master
                |-- (commit 2) - (commit 3) - demo
                \-- (commit 4) - (commit 5) - PRO

Ich habe einen git rebase mastervon PRO-Zweig ausprobiert , aber es passiert nichts.

Zur Verdeutlichung : Ich habe im Master gearbeitet und musste dann eine Produktdemo ( git checkout -b demound einige Commits) erstellen. Dann erstelle ich versehentlich einen weiteren Zweig aus der Demo ( git checkout -b PROund einigen Commits) und jetzt muss ich den PRO-Zweig verschieben, um die Demo zu meistern und intakt zu lassen. Am Ende hängen sowohl Demo als auch PRO vom Master.

Ivan
quelle
Mögliches Duplikat von Change Branch-Off Point
Wladimir Palant

Antworten:

278

Verwenden Sie --ontodafür:

git rebase --onto newBase oldBase feature/branch

In Anbetracht Ihres Falles:

git checkout PRO # Just to be clear which branch to be on.
git rebase --onto master demo PRO

Grundsätzlich nehmen Sie alle Commits von nach demobis zu PROund setzen sie erneut auf das masterCommit.

loganfsmyth
quelle
Ist das auch der richtige Weg, wenn die Situation umgekehrt ist? == Ich checke -b vom Master des zweiten Zweigs aus, aber ich wollte es vom ersten machen. Also habe ich es getan, git rebase --onto first-branch second-branch second-branchaber ich verstehe die Syntax nicht
Fla
1
@Fla in diesem Fall wäre esgit rebase --onto first-branch master second-branch
nVitius
9
Ich las diesen Leitfaden weiter --ontound wie sie schrieben, half mirgit rebase --onto newBase oldBase feature/branch
gabe
@PhilipRego Das ist falsch. origin/newBaseist der Name eines Zweigs, genau wie newBasein meinem Beispiel. Es hängt nur davon ab, ob Sie auf einen Zweig zurückgreifen, der in Ihrem lokalen Repository ( newBase) oder auf dem Remote- Repository ( ) vorhanden ist origin/newBase.
Loganfsmyth
@PhilipRego Das sind keine unabhängigen Dinge. newBaseist der Name eines lokalen Zweigs und origin/newBaseder Name eines Remote-Zweigs. Welches Sie wollen, hängt davon ab, worauf Sie sich stützen. Es ist nicht so, dass man arbeitet und man nicht, es ist so, dass sie sich auf verschiedene Dinge stützen. In der ursprünglichen Frage werden Fernbedienungen nie erwähnt, sodass die Verwendung von Fernbedienungen in meinem Beispiel nicht mit der gestellten Frage übereinstimmt.
Loganfsmyth
21

Ich werde versuchen, so allgemein wie möglich zu sein. Stellen Sie zunächst sicher, dass Sie sich in der gewünschten Branche befinden:

git checkout current-branch

Verwenden Sie dann den folgenden Befehl (wo new-base-branchist der Zweig, der Ihre neue Basis sein soll, und current-base-branchder Zweig, der Ihre aktuelle Basis ist.)

git rebase --onto new-base-branch current-base-branch

Wenn Sie keine Konflikte haben, dann großartig - Sie sind fertig. Wenn Sie dies tun (in den meisten Fällen), lesen Sie bitte weiter.

Es können Konflikte auftreten, die Sie manuell lösen müssen. Git versucht nun , einen „3-Wege - Merge“ zwischen zu tun current-branch, current-base-branchund new-base-branch. Ungefähr so ​​wird Git intern funktionieren:

  1. Git wird zuerst das current-base-branchoben auf dem neu starten new-base-branch. Es könnte Konflikte geben; die Sie manuell lösen müssen. Danach machen Sie normalerweise git add .und git rebase --continue. Hierfür wird ein neues temporäres Commit erstellt temp-commit-hash.

  2. Danach wird Git Ihr current-branchoben auf neu aufbauen temp-commit-hash. Es kann weitere Konflikte geben, die Sie erneut manuell lösen müssen. Sobald Sie fertig sind, fahren Sie erneut mit git add .und fort. git rebase --continueDanach haben Sie Ihre current-branchTop- Version erfolgreich neu aufgebaut new-base-branch.


Hinweis: Wenn Sie anfangen, git rebase --abortFehler zu machen, können Sie dies jederzeit während des Rebase-Vorgangs tun und zum Ausgangspunkt zurückkehren.

ARCHE
quelle
Der rebaseBefehl, wie er gepostet wurde, gibt mir nur "fatal: ungültiger Upstream 'Current-Base-Branch'". Warum ist es überhaupt notwendig, GIT mitzuteilen, was der aktuelle übergeordnete Zweig des aktuellen Zweigs ist - sollte es das nicht schon wissen?
Matt Arnold
19

Kasse zum PROVerzweigen, Kopieren Sie die ältesten ( commit4 ) und neuesten ( commit5 ) Commit-Hashes dieses Zweigs und fügen Sie sie an einer anderen Stelle ein:

$ git checkout PRO
$ git log            # see the commit history
# copy the oldest & latest commit-hash 

Löschen Sie den PROZweig (führen Sie aus Sicherheitsgründen ein Backup). Erstellen und Auschecken in einen neuen PROZweig von master:

$ git branch PRO.bac    # create a new branch PRO.bac = PRO as backup

$ git checkout master
$ git branch -D PRO     # delete the local PRO branch
$ git checkout -b PRO   # create and checkout to a new 'PRO' branch from 'master'

Nehmen Sie ( cherry-pick ) den Bereich der Festschreibungen von Zurück PRONiederlassung in den neuen PROZweig:

$ git cherry-pick commit4^..commit5   # cherry-pick range of commits
# note the '^' after commit4

Wenn nun alles in Ordnung ist, erzwingen Sie (-f) Push-to- remote PROBranch und löschen Sie den lokalen PRO.bacBranch:

$ git log                  # check the commit history

$ git push -f origin HEAD  # replace the remote PRO by local PRO branch history
# git branch -D PRO.bac    # delete local PRO.bac branch
Sajib Khan
quelle
1

Ich hatte einen etwas anderen Ansatz mit Reset und Stashes, der das Löschen und Neuerstellen von Zweigen vermeidet und das Wechseln der Zweige überflüssig macht:

$ git checkout PRO
$ git reset commit4 # This will set PROs HEAD to be at commit 4, and leave the modified commit 5 files in ur working index
$ git stash save -m "Commit message"
$ git reset commit 3
$ git stash save -m "Commit message"
$ git reset master --hard
$ git stash pop
$ git stash pop
$ git push --force # force if its already been push remotely

Wenn Sie den Zweig auf Commit-by-Commit-Basis zurücksetzen, spulen Sie im Grunde nur den Verlauf eines Commits nach dem anderen zurück.

Madjase
quelle
Sollten Sie das Leerzeichen zwischen "Festschreiben" und "3" in der 4. Zeile entfernen?
Alexis Wilke