简单来说,你不能(切换分支...好吧,有点可以,虽然你可以这样做,但不建议这样做—它会直接干涉Git的内部操作):
$ git checkout -b newbr
foo.txt: needs merge
error: you need to resolve your current index first
您的索引处于特殊的“合并”状态,因此您不能stash。幸运的是,没有必要这样做。(如果您解决了所有问题,然后运行git checkout -b newbr
并提交,您将获得一个非合并提交。您可以使用它,但让我们不要以这种方式处理。)
您应该继续完成合并:这给您想要的合并结果。然后,在您想要的分支中重新启动合并,并将刚才提交的结果作为您想要的结果获取,如果有必要的话。然后,完全丢弃原始的合并提交(如果需要的话)。(如果您意外地用成功的git checkout -b
破坏了合并,那么这也是您需要做的。)
在某些情况下,包括您的情况,原始合并的父连接是您想要的,只需要重新标记合并即可。
我会先展示步骤,然后解释为什么它能够工作:
... finish merging ...
$ git commit
$ git checkout -b AB-merge-branch
$ git checkout big-feature-branch-A
$ git reset --hard HEAD^
为什么这是一个答案(有多种方法,所以我不会说这是“唯一”的答案)
让我们把您开始合并时的设置绘制出来:
o--...--o--o <-- big-feature-branch-A (HEAD)
/
...--*
\
o--...--o--o <-- big-feature-branch-B
也就是说,你在“big-feature-branch-A”分支上,一切都很好,就像“git status”所表达的一样。每个“o”代表一个提交(而我用星号标记了合并基础,即合并点)。
然后,你本意是运行“git checkout -b AB-merge-branch”命令。如果你确实这样做了,图像将如下所示:
o--...--o--o <-- big-feature-branch-A, AB-merge-branch (HEAD)
/
--*
\
o--...--o--o <-- big-feature-branch-B
您运行了git merge
,但是遇到了冲突。您已经解决了(大部分)的冲突(在继续之前必须全部解决)。当您最终提交时,将会得到一个新的合并提交,并且这将移动当前分支(由HEAD
记住的分支):
o--...--o--o <-- big-feature-branch-A
/ \
--* M <-- AB-merge-branch (HEAD)
\ /
o--...--o--o <-- big-feature-branch-B
这里没有显示(因为很难显示出来)新合并的M
的第一个父提交是最右边(最新的)上一行的提交,第二个父提交是下方的提交。(这个第一个和第二个在稍后可能有所关系,当某人想要跟随“主”分支或“已合并的侧面功能”时:根据定义,“主”分支始终是第一个父提交。)
您忘记创建新的分支名称,因此现在会发生以下情况:
o--...--o--o
/ \
--* M <-- big-feature-branch-A (HEAD)
\ /
o--...--o--o <-- big-feature-branch-B
第一个父提交仍然是最上面和最右边的提交,第二个父提交仍然是底部的这样的提交。新的合并提交 M 是完全相同的。只是移动到指向新合并 M 的“标签”是 big-feature-branch-A(即 HEAD),而不是不存在的 AB-merge-branch(显然不是 HEAD)。
所以现在你只需创建想要的标签即可。任何使新分支名称 AB-merge-branch 指向 M 的内容都足够。您可以使用 git checkout -b AB-merge-branch 或 git branch AB-merge-branch 进行操作。
如果您使用 git checkout -b,则现在必须返回 big-feature-branch-A 以使用 git reset 进行修复(还有其他命令可用,但我在这里坚持使用 reset)。如果您使用 git branch 创建新分支,则不会影响当前分支:您仍在 big-feature-branch-A 上。
无论如何,您希望将此 big-feature-branch-A 分支名称向后移动一步,移回到 M 的第一个父提交,就好像它从未首先向前移动到 M 一样。因此,您回到(或保留在)该分支上。一旦您在此分支上,就可以使用 git reset --hard HEAD^ 实现此向后移动一步。HEAD^ 表示“找到 HEAD 的第一个父提交”,如果 HEAD 名称为提交 M(确实如此),则意味着最右上角的提交,这是您希望分支指向的位置。git reset 命令执行此分支重新定位,并且还重新设置索引和工作树(以便一切都干净地在新提交中)。