我刚刚花了最后几个小时来解决由于合并big-feature-branch-B到而导致的合并冲突big-feature-branch-A。我终于完成了,我所有的决议都已准备就绪,可以提出。但是,我工作的过程是:
big-feature-branch-A(我将其称为AB-merge-branch)big-feature-branch-B成AB-merge-branchAB-merge-branch到的PR big-feature-branch-A,以便解决方案可以通过代码审查。当我大部分时间都在解决合并冲突时,我意识到我正在解决它们big-feature-branch-A而不是合并分支。
我的问题是,如何在提交更改之前安全地更改分支?
我确信答案很简单,通常我只会存储我的更改,切换分支,然后弹出我的更改。但是,我从来没有在合并过程中这样做过,在这种情况下,我只是对“尝试”感到很ski跷,因为我不想冒险不得不再次解决所有这些冲突,而且我也不是超级对我的git-fu充满信心。我也读恐怖小说像这样(但也许我的情况是不同的,因为我已经解决了所有冲突,所有的改变都上演?),并且不觉得在这种情况下进行试验。谢谢!
简短的回答是你不能(切换分支......好吧,有点,虽然你可以,有点,但这是不可取的 - 它涉及直接与 Git 的内部进行猴子):
$ git checkout -b newbr
foo.txt: needs merge
error: you need to resolve your current index first
Run Code Online (Sandbox Code Playgroud)
您的索引处于这种特殊的“合并”状态,因此您也不能存储。幸运的是,没有必要这样做。(如果你解决了所有问题,然后运行git checkout -b newbr并提交,你会得到一个非合并提交。你可以使用它,但我们不要那样做。)
你应该做的是继续完成合并:这会给你你想要的合并结果。然后你可以在你想要的分支中重新开始合并,并获取你刚刚提交的结果作为你想要的结果,如果这甚至是必要的。然后完全丢弃原始合并提交(如有必要)。(如果您不小心破坏了合并成功git checkout -b,这也是您需要做的,几乎如上所示。)
在某些情况下——包括你的情况——原始合并的父链接是你想要的,这只是重新标记合并的问题。
我会先展示配方,然后解释它为什么起作用:
... finish merging ...
$ git commit # commit the merge
$ git checkout -b AB-merge-branch # create the merge branch
$ git checkout big-feature-branch-A # get back to other branch
$ git reset --hard HEAD^ # take the merge off of it
Run Code Online (Sandbox Code Playgroud)
让我们绘制您第一次开始合并时的设置:
o--...--o--o <-- big-feature-branch-A (HEAD)
/
...--*
\
o--...--o--o <-- big-feature-branch-B
Run Code Online (Sandbox Code Playgroud)
也就是说,正如git status所说的那样,您“在分支 big-feature-branch-A 上”并且一切都很好。每个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
Run Code Online (Sandbox Code Playgroud)
你跑了git merge,它因冲突而失败。您解决了(大部分)冲突(您必须在继续之前解决所有冲突)。当您最终提交时,您将获得一个新的合并提交,这将移动当前分支(由 记住的分支HEAD):
o--...--o--o <-- big-feature-branch-A
/ \
--* M <-- AB-merge-branch (HEAD)
\ /
o--...--o--o <-- big-feature-branch-B
Run Code Online (Sandbox Code Playgroud)
此处未显示(因为太难显示)是新合并的第一个父项M是最右边(最新)的上行提交,第二个是较低的。(当有人想要遵循“主”分支与“已合并的侧功能”时,这第一个和第二个东西稍后很重要:根据定义,主分支始终是第一个父分支。)
你忘了创建一个新的分支名称,所以现在发生的事情是这样的:
o--...--o--o
/ \
--* M <-- big-feature-branch-A (HEAD)
\ /
o--...--o--o <-- big-feature-branch-B
Run Code Online (Sandbox Code Playgroud)
第一个父级仍然是最顶部和最右侧的提交,第二个父级仍然是此类提交的底部。新的合并提交M是完全一样的。只是移动的标签指向新的 merge 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命名为 commit M(确实如此),则表示最右边的行提交,这是您希望分支指向的位置。该git reset命令会重新指向分支,并重新设置您的索引和工作树(以便所有内容都在新提交上干净利落)。
| 归档时间: |
|
| 查看次数: |
1528 次 |
| 最近记录: |