git rebase 交互:将提交合并在一起
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1725708/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
git rebase interactive: squash merge commits together
提问by Mildred
I wanted to have a simple solution to squash two merge commits together during an interactive rebase.
我想有一个简单的解决方案来在交互式 rebase 期间将两个合并提交压缩在一起。
My repository looks like:
我的存储库看起来像:
X --- Y --------- M1 -------- M2 (my-feature)
/ / /
/ / /
a --- b --- c --- d --- e --- f (stable)
That is, I have a my-feature
branch that has been merged twice recently, with no real commits in between. I don't just want to rebase the my-feature
branch since it is a published branch of its own, I just want to squash together the last two merge commits into one (haven't published those commits yet)
也就是说,我有一个my-feature
分支最近被合并了两次,中间没有真正的提交。我不只是想重新设置my-feature
分支,因为它是它自己的已发布分支,我只想将最后两个合并提交合并为一个(尚未发布这些提交)
X --- Y ---- M (my-feature)
/ /
/ /
a --- ... -- f (stable)
I tried:
我试过:
git rebase -p -i M1^
But I got:
但我得到了:
Refusing to squash a merge: M2
What I finally did is:
我最后做的是:
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
Now, the new merge commit is not considered a merge commit anymore (it only kept the first parent). So:
现在,新的合并提交不再被视为合并提交(它只保留了第一个父级)。所以:
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
But this can get complicated if I have many commits, do you have a better solution ? Thanks.
但是如果我有很多提交,这可能会变得复杂,你有更好的解决方案吗?谢谢。
Mildred
米尔德里德
回答by Matt
This is an old topic, but I just ran across it while looking for similar information.
这是一个古老的话题,但我只是在寻找类似信息时遇到了它。
A trick similar to the one described in Subtree octopus mergeis a really good solution to this type of problem:
类似于Subtree octopus merge 中描述的技巧是此类问题的一个非常好的解决方案:
git checkout my-feature
git reset --soft Y
git rev-parse f > .git/MERGE_HEAD
git commit
That will take the index as it exists at the tip of my-feature, and use it to create a new commit off of Y, with 'f' as a second parent. The result is the same as if you'd never performed M1, but gone straight to performing M2.
这将采用存在于 my-feature 尖端的索引,并使用它从 Y 创建一个新提交,'f' 作为第二个父级。结果就像您从未执行过 M1,而是直接执行 M2 一样。
回答by bobDevil
if you haven't published the last two merge commits, you could do a reset and a simple merge.
如果您还没有发布最后两个合并提交,您可以进行重置和简单合并。
git reset --hard Y
git merge stable
回答by Michael O'Cleirigh
I came to this topic wanting to squash a single merge commit; so my answer is not that useful to the original question.
我来到这个主题想要压缩单个合并提交;所以我的回答对原始问题没有那么有用。
X
\
\
a --- b --- c --- M1 (subtree merge)
What I wanted was to rebase the M1 merge and squash everything as a single commit on top of b.
我想要的是重新调整 M1 合并并将所有内容压缩为 b 之上的单个提交。
a --- b --- S (include the changes from c, X and M1)
I tried all kinds of different combinations but this is what worked:
我尝试了各种不同的组合,但这是有效的:
git checkout -b rebase b (checkout a working branch at point b)
git merge --squash M1
This will apply the changes into the index where they can be committed git commit
这会将更改应用到可以提交的索引中 git commit
回答by Michael Wild
None of the mentioned methods works for me with a recent git version. In my case the following did the trick:
对于最近的 git 版本,上述方法都不适用于我。在我的情况下,以下是诀窍:
git reset --soft Y
git reset --hard $(git commit-tree $(git write-tree) -p HEAD -p stable < commit_msg)
You'll have to write the commit message to the file commit_msg first, though.
不过,您必须先将提交消息写入文件 commit_msg。