git rebase interactive:squash merge commits together

我想要一个简单的解决scheme,在交互式重新绑定期间压缩两个合并提交。

我的资料库看起来像:

X --- Y --------- M1 -------- M2 (my-feature) / / / / / / a --- b --- c --- d --- e --- f (stable) 

也就是说,我有一个最近两次合并的my-feature分支,两者之间没有真正的提交。 我不只是想重新绑定my-feature分支,因为它是自己发布的分支,我只是想把最后两个合并提交合并为一个(还没有发布那些提交)

  X --- Y ---- M (my-feature) / / / / a --- ... -- f (stable) 

我试过了:

 git rebase -p -i M1^ 

但是我得到了:

 Refusing to squash a merge: M2 

我最终做的是:

 git checkout my-feature git reset --soft HEAD^ # remove the last commit (M2) but keep the changes in the index git commit -m toto # redo the commit M2, this time it is not a merge commit git rebase -p -i M1^ # do the rebase and squash the last commit git diff M2 HEAD # test the commits are the same 

现在,新的合并提交不再被视为合并提交(它只保留第一个父代)。 所以:

 git reset --soft HEAD^ # get ready to modify the commit git stash # put away the index git merge -s ours --no-commit stable # regenerate merge information (the second parent) git stash apply # get the index back with the real merge in it git commit -a # commit your merge git diff M2 HEAD # test that you have the same commit again 

但如果我有很多提交,这可能会变得复杂,你有更好的解决scheme吗? 谢谢。

米尔德里德

这是一个古老的话题,但我只是在寻找类似的信息的时候碰到了它。

类似于Subtree章鱼合并中描述的技巧对于这种types的问题是一个非常好的解决scheme:

 git checkout my-feature git reset --soft Y git rev-parse f > .git/MERGE_HEAD git commit 

这将采取索引,因为它存在于我的function的尖端,并使用它来创build一个新的提交从Y,与'f'作为第二个父母。 结果就像你从未执行M1一样,但直接执行M2。

如果你还没有发布最后两个合并提交,你可以做一个重置和一个简单的合并。

 git reset --hard Y git merge stable 

我来到这个想要压缩一个合并提交的话题; 所以我的回答对原始问题没有什么用处。

  X \ \ a --- b --- c --- M1 (subtree merge) 

我想要的是重新M1合并和压缩一切作为一个单一的提交上b。

 a --- b --- S (include the changes from c, X and M1) 

我尝试了各种不同的组合,但这是什么工作:

 git checkout -b rebase b (checkout a working branch at point b) git merge --squash M1 

这将把更改应用到可以提交git commit的索引处

没有一个提到的方法适用于我最近的git版本。 在我的情况下,下面的伎俩:

 git reset --soft Y git reset --hard $(git commit-tree $(git write-tree) -p HEAD -p stable < commit_msg) 

不过,您必须首先将提交消息写入文件commit_msg。