在执行部分合并之后,如何重新合并分支

时间:2014-12-10 14:14:14

标签: git merge git-merge

所以我执行了部分合并(通过git merge --no-commit)只从featureA分支引入了一些更改。然后在featureB分支中合并。现在我需要来自featureA的其他更改。 Git说,如果我再次合并featureA,那就无所事事了,因为Git认为它已经被合并了。

以下是尝试解释我正在尝试做什么

       featureB ,-------.
               /         \(merge)
master----+---+-----+-----+------------+---  
           \       /(partial merge)   /(TODO: merge in rest of featureA)
   featureA `-----'..................'
                   (no changes here)

是否有一个简单的命令在git中执行此操作?

2 个答案:

答案 0 :(得分:3)

以下文字的tl; dr是:master反映了自A错误合并以来的累积差异。您希望将正确的合并结果作为不正确的合并子进行提交,因此当您将正确的结果合并回master并合并两个提示时,它会看到并合并不正确的合并与正确的合并之间的差异。 / p>

这里是如何,叙述或多或少地反映了我如何得到这个结果。


您现在拥有的合并基础,功能A提示,您不想要。从那以后,master之后没有任何变化与之后的更改合并。如果您在原始合并中完成了整个工作,您需要合并历史记录和结果。提交图的精简版,供参考:

#            /-B.....-\         featureB
#   ---A0---B0---APM---BM---?   master [APM, featureA partial merge, is bad]
#       \-A...../??????????/    featureA [can keep history, merge rest of A?]

第一步是首先获得你想要的合并结果:

# redo the original merge to get the right parents and the right content
git checkout $APM^        # checkout the original merge parent
git merge $APM^2          # do the correct merge with its other parent
git checkout -b AM        # give this work a name

现在你有:

#            /-B......\
#   ---A0---B0---APM---BM---?
#       \     \-/-AM
#        \-A.../-/

其中AM具有与$APM相同的父项,但结果正确。 $APM现在AM中的AM做了正确的事情:$APM体现了需要对$APM进行更改以获得正确结果的更改。 AM提交中的所有内容已生效(在字面效果中)合并到git merge -s ours $APM # $APM is correctly incorported in AM. Tell git.

AM

这使得历史记录正确:$APM反映了master的一组更改,git checkout master git merge AM 反映了另一组。合并它们的时间:

git branch -d AM

git clone -s . ../wip # safety play: sandbox the changes # do the above, and when you're satisfied you've got `master` correct, cd ../$mainrepo git checkout master # okay, incorporate the results git pull # . rm -rf ../wip # (everything in wip is now also here) 如果我做对了,你就完成了。


以防万一我遇到了问题,作为提醒或注意事项,请在备忘录中执行以上操作:

# drop this as file `script` in an empty directory and
# say `sh script` to recreate the described situation:

set -x
git init --template=
for f in {1..5}; do seq -ffile$f%4.0fx 10 >f$f; done
git add .
git commit -m'Initial commit'
git checkout -b featureA
sed -si s/4x/4-featureA/ f2 f3
git commit -am4featureA-f2f3
git checkout master
sed -si s/1x/1-master/ f1 f2 f3
git commit -am1master-f1f2f3
git checkout -b featureB
sed -si s/8x/8-featureB/ f3 f4
git commit -am8featureB-f3f4
git checkout master
git merge --no-commit featureA
git checkout HEAD f3
git commit -m'Merge branch featureA - less the f3 changes'
git tag APM
git merge --no-edit featureB

# and test the given solution:

git checkout -b AM APM^
git merge --no-edit featureA
git merge --no-edit -s ours APM
git checkout master
git merge --no-edit AM

# say `rm -rf f* .git` to cleanup

测试:

{{1}}

答案 1 :(得分:1)

IMO部分合并,因为您描述它们是邪恶的,因为您现在遇到的原因和其他事情。

例如:与您的存储库一起工作的任何开发人员都希望master包含featureA的所有更改。这可能会导致很多混乱。


注意:我假设您当前位于存储库的根目录和主分支上。

你有效地有两个简单的选择:

  1. 您使用git checkout --merge featureA -- .featureA的其余更改合并到master - 在这种情况下,您将无法进行合并提交

  2. 您在git commit --allow-empty上进行空提交(featureA),然后再次合并

  3. 正如您所看到的,两种解决方案都不是最佳的,这是您部分合并的结果。

    最干净的方法是恢复旧的合并,将featureA拆分为多个提交,并仅合并必要的提交。然后你可以稍后合并其余的 这显然也是最有效的方法。

    我个人建议选择1.或2.并避免将来合并。


    编辑 我尝试使用this answer中描述的方法手动创建合并提交。但似乎git认识到featureA已经合并并抛弃第二个父级的事实,这导致简单而不是合并提交。