git rebase交互:挤压合并提交到一起

git rebase交互:挤压合并提交到一起,git,merge,interactive,rebase,squash,Git,Merge,Interactive,Rebase,Squash,我希望有一个简单的解决方案,在交互式重新基址期间将两个合并提交挤压在一起 我的存储库看起来像: X --- Y --------- M1 -------- M2 (my-feature) / / / / / / a --- b --- c --- d --- e --- f (stable) 也就是说,我有一个myfeature分支,最近已经合并了两次,中间没有真正的提交。我不仅

我希望有一个简单的解决方案,在交互式重新基址期间将两个合并提交挤压在一起

我的存储库看起来像:

   X --- Y --------- M1 -------- M2 (my-feature)
  /                 /           /
 /                 /           /
a --- b --- c --- d --- e --- f (stable)
也就是说,我有一个
myfeature
分支,最近已经合并了两次,中间没有真正的提交。我不仅仅想重新设置
my feature
分支的基础,因为它本身就是一个已发布的分支,我只想将最后两个合并提交压缩为一个(尚未发布这些提交)

我试过:

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
现在,新的合并提交不再被视为合并提交(它只保留第一个父级)。因此:

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


Mildred

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

git reset --hard Y
git merge stable

这是一个老话题,但我只是在寻找类似信息时偶然发现了它

类似于中所述的技巧是解决此类问题的非常好的方法:

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

这将使索引保持在我的特性的顶端,并使用它创建Y的新提交,其中“f”作为第二个父级。结果与您从未执行过M1,但直接执行过M2的结果相同。

提到的所有方法都不适用于我最新的git版本。在我的例子中,以下几点起到了作用:

git reset --soft Y
git reset --hard $(git commit-tree $(git write-tree) -p HEAD -p stable < commit_msg)
git重置——软Y
git reset--hard$(git提交树$(git写入树)-p HEAD-p stable

不过,您必须先将提交消息写入commit\u msg文件。

我来到这个主题是想压缩单个合并提交;所以我的回答对原来的问题没有多大用处

               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

好吧,当您进行第二次合并时,您可以始终使用
--squash
来避免创建提交,然后使用
git commit--amend
来修改以前的合并。这不起作用,它不会将您合并的分支的新版本保存到委员会中,但合并很困难,我宁愿合并尽可能少的更改。我不想解决我已经解决的冲突。如果你不想重新解决冲突,你需要“使用”git Reere(而“使用”实际上是指“打开它”,因为一旦启用,git会自动处理重新修复相同的冲突)。请注意,这种合并与子树或八达通合并无关。您链接的博客只是使用这种技术将子树合并和八达通合并合并为一个合并提交(因为git不能一次直接完成两个合并)。其缺点是git无法生成正确的提交消息。我从旧的合并提交中复制了消息。否则,这是一个很好的、简单的解决方案。这么多的投票!我们刚刚做了一个非常困难的合并,我的同事们的方法是将每个提交从他的树合并到我的树,一次一个。然后是挤压,我们找到了这个解决方案。很遗憾,您需要编写自己的提交消息。如果启动失败的合并,您可以获得合并消息的内容,然后使用它。我更喜欢使用
git update ref merge\u HEAD f
而不是
git rev parse f>.git/merge\u HEAD
,因为它不会直接修改内部git文件。如果我编辑该部分可以吗?对于这种情况,您可以执行
git diff b>diff.patch
,然后执行
git checkout b
cat diff.patch | patch-p1
,然后执行
git commit
。如果合并包含分辨率,则此操作有效。原来的问题是不同的;但我想你来这里是为了和我一样的东西。您可以使用
git log
事先获取签入消息。如果您想了解主机上的情况,需要执行其他步骤:
git checkout master和&git reset--hard b和&git rebase
。这只是为了我自己。您可以为分支选择除“rebase”之外的另一个名称:)您可以用$($EDITOR commit_msg)替换commit_msg,或者编写
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