繁体   English   中英

如何使用git rebase来压缩合并周围的提交?

[英]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^2The merged branch commit M的第二个父级The merged branch 如果失败(或者如果你想修改它,添加--no-commit ,现在你就停止它了),你可以通过直接从commit M检查文件来修复合并,假设你想要你拥有相同的合并分辨率那里。

(如果你启用了git rerere ,那么大部分都会在此时自动发生。)

一旦你提交,或合并完成后,你有新的合并的ID提交m

现在你已准备好挑选提交DE包括:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM