2009-11-12 126 views
49

我想要一个简单的解决方案,在交互式rebase期间压缩两个合并提交。git rebase interactive:squash merge commit在一起

我的库看起来像是:

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 

但这可能很复杂,如果我有很多的提交,你有一个更好的解决办法? 谢谢。

米尔德里德

+0

那么,当你做第二次合并,你总是可以使用'--squash'来避免创建提交,然后使用'git commit --amend'来修改以前的合并。 – Mildred 2009-11-12 22:42:56

+0

这不起作用,它不会保存您在合并中提交的分支的新版本 – Mildred 2009-11-13 10:59:48

回答

8

如果你还没有公布最后两个合并提交,你可以做一个复位和简单合并。

git reset --hard Y 
git merge stable 
+2

是的,但合并很困难,我宁愿尽可能少地进行合并。我不想解决我已经解决的冲突。 – Mildred 2009-11-13 11:02:58

+9

如果你不想重新解决冲突,你需要“使用”git-rerere(和“使用”我的意思是“打开它”,因为一旦这是git句柄自动重新修复相同的冲突启用)。 – 2009-11-13 13:43:56

47

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

类似于Subtree octopus merge所述类似的伎俩是一个很好的解决了这一类型的问题:

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

,因为它存在于我的,功能的提示,将采取指数,并用它创造一个新的承诺Y,与'f'作为第二个父母。结果与您从未执行过M1相同,但直接执行M2。

+0

请注意,这种合并与子树或章鱼合并无关。您链接的博客仅使用该技术*将子树合并和章鱼合并合并为一个合并提交(因为git不能直接同时执行两个合并)。 – sleske 2013-10-30 11:06:20

+0

这样做的缺点是git将无法生成正确的提交消息。我复制了旧合并提交中的消息。否则,一个不错的,简单的解 – 2014-07-28 09:21:16

+0

这么多upvote!我们只是做了一次非常困难的合并,我的同事们的做法是将他树上的每个提交合并到一次,一次一个。然后来到挤压和我们找到这个解决方案。你需要编写自己的提交消息是一种耻辱。 – Sam 2014-10-21 15:06:06

0

上述方法都不适用于最近的git版本。在我的情况下,下面的伎俩:

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

你必须写提交信息到文件commit_msg第一,虽然。

5

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

   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的承诺

+1

对于这种情况,您可以执行'git diff b> diff.patch',然后'git checkout b','cat diff.patch | patch -p1'然后'git commit'。这适用于*合并*包含分辨率。原来的问题是不同的;但我认为你来到这里寻找和我一样的东西。您可以事先用'git log'获得登记信息。 – 2014-09-22 21:09:33

+0

如果您想要掌握master的情况,需要执行其他步骤:'git checkout master && git reset --hard b && git rebase rebase'。这只是为了给自己留下深刻的印象。你可以为分支选择另一个名称而不是“rebase”:) – eis 2017-05-22 16:12:03