git rebase interactive:squash merge提交在一起

Mil*_*red 52 git merge interactive rebase squash

我希望有一个简单的解决方案,可以在交互式rebase期间将两个合并提交压缩在一起.

我的存储库看起来像:

   X --- Y --------- M1 -------- M2 (my-feature)
  /                 /           /
 /                 /           /
a --- b --- c --- d --- e --- f (stable)
Run Code Online (Sandbox Code Playgroud)

也就是说,我有一个my-feature最近合并过两次的分支,中间没有真正的提交.我不只是想重新定义my-feature分支,因为它是它自己的已发布分支,我只想将最后两个合并提交压缩成一个(还没有发布那些提交)

   X --- Y ---- M (my-feature)
  /            /
 /            /
a --- ... -- f (stable)
Run Code Online (Sandbox Code Playgroud)

我试过了:

git rebase -p -i M1^
Run Code Online (Sandbox Code Playgroud)

但我得到了:

Refusing to squash a merge: M2
Run Code Online (Sandbox Code Playgroud)

我最后做的是:

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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

但是如果我有很多提交,这会变得复杂,你有更好的解决方案吗?谢谢.

米尔德里德

小智 49

这是一个古老的话题,但我在寻找类似信息时遇到了它.

类似于所述类似的伎俩子树章鱼合并是一个非常好的解决了这一类型的问题:

git checkout my-feature
git reset --soft Y
git rev-parse f > .git/MERGE_HEAD
git commit
Run Code Online (Sandbox Code Playgroud)

因为它存在于我的,功能的提示,将采取指数,并用它来创建一个新的提交过的Y,用"F"作为第二父.因为如果你从来没有进行M1,而是直接去了在执行M2的结果是一样的.

  • 我更喜欢使用`git update-ref MERGE_HEAD f`而不是`git rev-parse f> .git/MERGE_HEAD`,因为它不直接修改内部git文件.如果我编辑那部分可以吗? (8认同)

bob*_*vil 8

如果您尚未发布最后两个合并提交,则可以执行重置和简单合并.

git reset --hard Y
git merge stable
Run Code Online (Sandbox Code Playgroud)

  • 如果你不想重新解决冲突,你需要"使用"git-rerere(和"使用"我的意思是"打开它"'因为git会在启用后自动重新修复相同的冲突). (10认同)
  • 是的,但合并很困难,我宁愿合并尽可能少的变化.我不想解决我已经解决的冲突. (2认同)

Mic*_*igh 5

我来到这个主题想要压缩单个合并提交; 所以我的答案对原始问题没那么有用.

               X
                \   
                 \  
a --- b --- c --- M1 (subtree merge)
Run Code Online (Sandbox Code Playgroud)

我想要的是重新定义M1合并并将所有内容压缩为b之上的单个提交.

a --- b --- S (include the changes from c, X and M1)
Run Code Online (Sandbox Code Playgroud)

我尝试了各种不同的组合,但这是有效的:

git checkout -b rebase b (checkout a working branch at point b)
git merge --squash M1
Run Code Online (Sandbox Code Playgroud)

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