![](/img/trans.png)
[英]How to Git rebase interractively squash few commits before merge commit
[英]How to use git rebase to squash commits around a merge?
使用git进行合并的最简单方法是什么?
在我的一个分支机构中,我一直在玩着许多不同的东西,包括大量失败和部分失败的尝试。 现在我已经开始工作了,我想回过头来使用交互式变基,压制一堆猜测和检查提交。
复杂的是,在这个过程中我合并了另一个分支。 我想保持合并分支的原样(不重写任何提交),并将合并提交保持在我的分支中相同的相对位置。 (因为我的分支中的功能依赖于之前/之后。)我尝试做一个直接的git rebase -i
,但我合并的分支从我最后分歧的点开始有相当数量的提交,并且因为它们显示在交互式rebase文件中,它们使事情变得复杂。
图表可能有所帮助。 我现在拥有的:
#-#-#-#-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* My branch
\ /
#-#-#-#-#-#-#-#-#-#-#-#-# The merged branch
我想要的是:
#-#-#-#-----*-------*-*----*------* My branch
\ /
#-#-#-#-#-#-#-#-#-#-#-#-# The merged branch
(“#”是我想要保持相同的提交,SHA1方式,两个合并提交的文件系统内容应该相同。)
我没有将我想要的任何提交推送到远程服务器。 (虽然我合并分支是在远程服务器上。)
DavidN的答案是正确的 - 请记住,rebase只是复制提交 - 但执行起来有点棘手。 您需要保存两个特定的提交ID,甚至可能使用另一个分支名称。
我实际上会用一个新的分支名称和git cherry-pick
以及一个新的git merge
做到这一点,我自己。 这是方法,使用您的图表,稍微注释,以及一些实际的Git命令。 你有:
A-#-#-B-*-*-*-*-*-*-CMD-*-*-*-*-*-*-E My branch \\ / #-#-#-#-#-#-#-#-#-#-#-#-# The merged branch
你要:
A-#-#-B-----*-------*-m----*------* My branch \\ / #-#-#-#-#-#-#-#-#-#-#-#-# The merged branch
你可以从:
git checkout -b rebased B
它会为您提供一个指向提交B
的新分支名称。 现在你可以:
git cherry-pick -n B..C
(或使用原始ID)复制B
之后的所有*
提交并包括C
,然后git rebase -i B
并压缩一些以获得你的两个*
提交。
现在你已准备好合并; 所以git merge M^2
与The merged branch
commit M
的第二个父级The merged branch
。 如果失败(或者如果你想修改它,添加--no-commit
,现在你就停止它了),你可以通过直接从commit M
检查文件来修复合并,假设你想要你拥有相同的合并分辨率那里。
(如果你启用了git rerere
,那么大部分都会在此时自动发生。)
一旦你提交,或合并完成后,你有新的合并的ID提交m
。
现在你已准备好挑选提交D
到E
包括:
git cherry-pick D^..E
(我们需要D^
这里得到D
- 或者你可以使用提交M
的原始SHA-1 ID,原始合并)。 然后git rebase -im
只重新设置D
through- E
的新副本,而无需通过新的合并m
进行备份。
完成后,您将获得所需的图表。 分支的名称rebased
,而不是My branch
,虽然,1,你有分支My branch
指向提交E
。 所以git checkout My branch
然后git reset --hard rebased
在新的branch-tip-commit中git reset --hard rebased
指向旧名称,之后你可以删除名称rebased
。
1显然这不是实际名称,因为在分支名称中有一个空格是坏的。
您可以采用手动方法,只需在MyBranch的第一个分支提交到TheMergedBranch之间在MyBranch上进行交互式变基,以压缩您的东西。 然后在TheMergedBranch中合并。 然后做一个交互式的rebase - 你的新分支与上游和提交从原来的MyBranch获取那些。
不要使用rebase,使用移植物。 请记住,提交是完全内容的快照,因此您想要的提交与现有提交的内容完全相同,您只想重新连接父系。 这就是移植物的用途。
首先,在沙盒仓库中执行此操作,以便您可以放弃并擦除它,如果您不喜欢正在发生的事情:
git clone -s . "${other=`mktemp -dt`}"
cd "$other"
设置所需的父母
echo > .git/info/grafts $(git rev-parse M B M^2)
echo >>.git/info/grafts $(git rev-parse E M)
(我想你在那里有一两个你想要的提交,只要列出你真正想要的父母的提交代替你已经获得的提交,git的修订版将跟随你的领导)
然后
git filter-branch -- --all
如果你喜欢结果推回他们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.