所以我执行了部分合并(通过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中执行此操作?
答案 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
的所有更改。这可能会导致很多混乱。
注意:我假设您当前位于存储库的根目录和主分支上。
你有效地有两个简单的选择:
您使用git checkout --merge featureA -- .
将featureA
的其余更改合并到master
- 在这种情况下,您将无法进行合并提交
您在git commit --allow-empty
上进行空提交(featureA
),然后再次合并
正如您所看到的,两种解决方案都不是最佳的,这是您部分合并的结果。
最干净的方法是恢复旧的合并,将featureA
拆分为多个提交,并仅合并必要的提交。然后你可以稍后合并其余的
这显然也是最有效的方法。
我个人建议选择1.或2.并避免将来合并。
编辑 我尝试使用this answer中描述的方法手动创建合并提交。但似乎git认识到featureA
已经合并并抛弃第二个父级的事实,这导致简单而不是合并提交。