如何压缩实际在合并提交之前的两个提交?

时间:2015-07-03 08:59:31

标签: git git-merge rebase git-rewrite-history

假设以下历史记录:

   X - Y - M - Z   <- feature
 /        /
A - B - C - D      <- master

我想重写历史记录以将X和Y修复为单个提交。所以我希望历史看起来像这样:

    X' -   M'- Z'  <- feature
 /        /
A - B - C - D      <- master

到目前为止,我所有的尝试都失败了。大多数时候在rebase期间存在冲突。也许rebase不是实现这个目标的正确方法吗?

我理解(不知道合并之前的有效情况还没有真正改变)重新应用从主设备到功能(M)的合并导致我在第一个地方解决的相同冲突。命令&#39; rerere&#39;可能是一个解决这个问题的选择,但据我所知,这只有在可以解决这个问题的情况下才有可能。一开始也被激活了。

但在这种情况下,X-Y确实具有与X&#39相同的变更集。为什么git不够聪明才能重新申请M?如果我只是在单个提交X&#39;中压缩X和Y,原始解析的更改(存储在M中)应该再次是M&#39;的正确内容。我怎么能告诉git只需要用M的旧内容来构建M&#39; ?

4 个答案:

答案 0 :(得分:1)

echo `git rev-parse Y A` >.git/info/grafts
git filter-branch -- --all
rm .git/info/grafts

filter-branch docs

移植物是回复本地血统的覆盖物。看到祖先的git中的任何东西都会看到嫁接的祖先,特别是重写提交的东西会看到它并将其烘焙到重写的提交中。

过滤器是shell脚本片段,如果您想提供新的提交消息,例如

git filter-branch --msg-filter="
        [ \$commit = `git rev-parse Y` ] && cat <&3 || cat" -- --all 3<<EOD
your new commit message subject

your new commit message body here
...
EOD

答案 1 :(得分:0)

git checkout feature
git checkout HEAD~2
git rebase -i HEAD~2

壁球最后两次提交。然后使用git cherry-pick使用MZ重写历史记录。

希望有所帮助。

答案 2 :(得分:0)

在我发现黑客时回答我的问题。我希望git可以做得更好/更容易,所以我仍然要求更好的解决方案...

黑客是在没有提交的情况下再次启动合并。然后将原始合并(M)中的所有更改读入索引并完成合并。需要重置才能清除工作目录中的冲突文件。之后继续樱桃采摘Z ...

git checkout -b featureRewritten A
git cherry-pick X
git cherry-pick -n Y
git commit --amend           #this will actually fixup Y into X
git merge -n C               #start the merge without commit
git read-tree M              #throw away the staged merge results by
                             #replacing them with the original solution
git commit                   #finish commit. need to change the automsg?
git reset --hard HEAD        #throw away any left overs
git cherry-pick Z            #continue

历史悠久的艰苦工作......更好的解决方案?

答案 3 :(得分:0)

另一种解决方案(基于jthill的想法):

git checkout Y
git rebase -i A
#i-rebase: reword X
#i-rebase: fixup Y
git replace Y HEAD
git filter-branch -- --all --ancestry-path Y^!
git replace -d Y

首先结帐到分离的Y(一个以Y结尾的未命名分支)。交互式rebase将Y合并到X中并重新描述X的消息。结果是新的提交N.HEAD当前指向它。现在Y(仍然是分支特征的一部分)被N(HEAD)取代。使用filter-branch制作永久物。删除Y的替换以消除N.