我花了最后几个小时来解决因将big-feature-branch-B
合并到big-feature-branch-A
而导致的合并冲突。我终于完成了,我的所有决议都已上演并准备好承诺。但是,我工作的过程是:
big-feature-branch-A
创建分支(我将此分支称为AB-merge-branch
)big-feature-branch-B
合并到AB-merge-branch
AB-merge-branch
合并到big-feature-branch-A
中,以便解决方案可以通过代码审核。 当我通过解决合并冲突的大部分时间时,我意识到我在big-feature-branch-A
而不是合并分支中解析它们。
我的问题是,如何在提交更改之前安全地更改分支?
我确信答案很简单,通常我会隐藏我的更改,切换分支,然后弹出我的更改。但是,我从来没有在合并过程中做到这一点,在这种情况下,我对于“尝试它”非常怯懦,因为我不想冒险再次解决所有这些冲突,而且我不是超级对我的git-fu充满信心。我也读过像this这样的恐怖故事(但也许我的情况有所不同,因为我已经解决了所有的冲突,所有的变化都是上演的?),并且不想在这种情况下进行实验。谢谢!
答案 0 :(得分:2)
简短的回答是你不能(切换分支......好吧,有点,尽管你可以,但是它不可取 - 它涉及直接用Git的内脏进行修改):
$ git checkout -b newbr
foo.txt: needs merge
error: you need to resolve your current index first
您的索引处于此特殊“合并”状态,因此您也无法存储。幸运的是,没有必要这样做。 (如果你解决了所有问题,然后运行git checkout -b newbr
并提交,你会得到一个非合并提交。你可以使用它,但是不要这样做。)
您应该做的是继续并完成合并:这将为您提供所需的合并结果。然后,您可以在所需的分支中重新启动合并,并将您刚刚提交的结果作为结果获取,如果有必要的话> EM>。然后,您完全放弃原始合并提交(如有必要)。 (如果您不小心使用上面几乎显示的成功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
让我们绘制您第一次开始合并时的设置:
o--...--o--o <-- big-feature-branch-A (HEAD)
/
...--*
\
o--...--o--o <-- big-feature-branch-B
也就是说,正如git status
所说的那样,“你在分支大特征分支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
您运行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
,则现在必须将返回<{1}}以使用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
命令重新指向分支,并重新设置索引和工作树(以便新提交中的所有内容都干净利落)。
答案 1 :(得分:1)
首先,完成合并并提交。这样,你就不会失去任何东西 这是一项本地行动,不会被其他任何人看到。
从该提交中,您可以创建分支AB-merge-branch
git checkout -b AB-merge-branch
您可以将之前的big-feature-branch-A
重置为其第一个父提交。
git branch --force big-feature-branch-A big-feature-branch-A^1