使用合并提交将提交移动到新分支
Move commits into new branch with merge commits
我有这样的线性历史
----a--b--c--d--e--f---- main
我想将一系列提交移动到一个新分支中,并在旧分支中创建一个合并提交,创建一个像这样的非线性历史
----a-------x--d'--e'--f'-- main
\ /
b--c
其中 x
是新的合并提交。
我该怎么做?
请注意,移动的提交不是最新的(请参阅 here)。
你可以很容易地做到这一点,但你将重写 main
的历史记录,这是不推荐的,可能必须强制推送到远程。
无论如何,这是你的初始情况,或多或少(我使用 master
而不是 main
,我只达到了 e
):
$ git log --oneline --graph --all
* d5de97b (HEAD -> master) e
* 97f47d1 d
* 7c33da9 c
* 295b3c7 b
* 18622aa a
好的,我建议将 b
和 c
变成分支 feature
上的提交,该分支将在 d
之前合并到 master
中。准备好? (其中一些步骤,例如某些 checkout
动作,可能是不必要的,但我没有停下来担心这个。)
$ git branch holdmyplace # prevent losing any commits
$ git branch feature 7c33da9 # call `c` by a branch name `feature`
$ git reset --hard 18622 # slide `master` all the way back to `a`...
$ git merge --no-ff feature # ...and merge `feature` with a merge commit!
$ git checkout holdmyplace # okay, now return to the placeholder branch...
$ git rebase --onto master feature holdmyplace
# ...and append it to `master`
$ git checkout master # finally, return to master...
$ git reset --hard holdmyplace # ...and slide it back up to the end!
$ git branch -d holdmyplace # we no longer need the placeholder branch
现在我们有:
$ git log --oneline --graph --all
* 0d58dd1 (HEAD -> master) e
* 7831073 d
* 2bd7688 Merge branch 'feature'
|\
| * 7c33da9 (feature) c
| * 295b3c7 b
|/
* 18622aa a
你说的就是你想要的。
让我们从创建一些指针开始,让事情变得更简单。
git branch base <a>
git branch feat <c>
图表看起来像这样。
----a--b--c--d--e--f---- main
^ ^
base feat
现在我们将 feat
合并到 base
,创建合并提交。
git switch base
git merge --no-ff feat
图表现在看起来像这样。
----a------x base
\ /
b--c--d--e--f-- main
现在我们将 main
变基到 base
,将其移动到新的合并提交上。
git switch main
git rebase --onto base feat
最后,我们可以清理不再需要的指针。
git branch -d base
git branch -d feat
我们最终得到如下图。
----a------x--d'--e'--f'-- main
\ /
b--c
这就是我要做的:
git checkout a
git merge --no-ff c
git cherry-pick c..main
# at this point you are on a revision that has a history like what you asked for
# now it's time to move main
git branch -f main
git checkout main
如果您将该分支推送到其他存储库,则必须强制推送新分支,因为您重写了它的历史记录。 (你重写历史还有其他考虑,以防万一)。
我有这样的线性历史
----a--b--c--d--e--f---- main
我想将一系列提交移动到一个新分支中,并在旧分支中创建一个合并提交,创建一个像这样的非线性历史
----a-------x--d'--e'--f'-- main
\ /
b--c
其中 x
是新的合并提交。
我该怎么做?
请注意,移动的提交不是最新的(请参阅 here)。
你可以很容易地做到这一点,但你将重写 main
的历史记录,这是不推荐的,可能必须强制推送到远程。
无论如何,这是你的初始情况,或多或少(我使用 master
而不是 main
,我只达到了 e
):
$ git log --oneline --graph --all
* d5de97b (HEAD -> master) e
* 97f47d1 d
* 7c33da9 c
* 295b3c7 b
* 18622aa a
好的,我建议将 b
和 c
变成分支 feature
上的提交,该分支将在 d
之前合并到 master
中。准备好? (其中一些步骤,例如某些 checkout
动作,可能是不必要的,但我没有停下来担心这个。)
$ git branch holdmyplace # prevent losing any commits
$ git branch feature 7c33da9 # call `c` by a branch name `feature`
$ git reset --hard 18622 # slide `master` all the way back to `a`...
$ git merge --no-ff feature # ...and merge `feature` with a merge commit!
$ git checkout holdmyplace # okay, now return to the placeholder branch...
$ git rebase --onto master feature holdmyplace
# ...and append it to `master`
$ git checkout master # finally, return to master...
$ git reset --hard holdmyplace # ...and slide it back up to the end!
$ git branch -d holdmyplace # we no longer need the placeholder branch
现在我们有:
$ git log --oneline --graph --all
* 0d58dd1 (HEAD -> master) e
* 7831073 d
* 2bd7688 Merge branch 'feature'
|\
| * 7c33da9 (feature) c
| * 295b3c7 b
|/
* 18622aa a
你说的就是你想要的。
让我们从创建一些指针开始,让事情变得更简单。
git branch base <a>
git branch feat <c>
图表看起来像这样。
----a--b--c--d--e--f---- main
^ ^
base feat
现在我们将 feat
合并到 base
,创建合并提交。
git switch base
git merge --no-ff feat
图表现在看起来像这样。
----a------x base
\ /
b--c--d--e--f-- main
现在我们将 main
变基到 base
,将其移动到新的合并提交上。
git switch main
git rebase --onto base feat
最后,我们可以清理不再需要的指针。
git branch -d base
git branch -d feat
我们最终得到如下图。
----a------x--d'--e'--f'-- main
\ /
b--c
这就是我要做的:
git checkout a
git merge --no-ff c
git cherry-pick c..main
# at this point you are on a revision that has a history like what you asked for
# now it's time to move main
git branch -f main
git checkout main
如果您将该分支推送到其他存储库,则必须强制推送新分支,因为您重写了它的历史记录。 (你重写历史还有其他考虑,以防万一)。