git 如何用普通提交挤压合并提交?

o3imoua4  于 2022-12-02  发布在  Git
关注(0)|答案(2)|浏览(237)
commit b0e5db36ed68d4562275adeb08001b1316a4da52
Merge: ea38baa 8220bb1

commit ea38baa3f46a48722987b8dd3892d2b8d81c4d1a

在这种情况下,我如何压缩这两个提交
我正在使用

git rebase -i HEAD~2

但这不起作用,因为它删除了合并提交,并且该提交不可用于压缩

nxagd54h

nxagd54h1#

所以这里要考虑两个因素:
首先,在某些方面,rebase并不总是很好地处理合并提交。
第二,我们并不完全清楚你期望的结果是什么。

x -- x -- M -- C <--(master)
 \       /
  A --- B

你是不是想

x -- x -- ABC <--(master)

x -- x -- MC <--(master)
 \       /
  A --- B

如果您希望得到包含ABC的版本,这非常简单。虽然M没有出现在rebase的TODO列表中,由 * M带入主线 * 的所有提交(即本例中的AB)是。所以只需将BC标记为"squash"。唯一需要记住的是,这是一次历史重写,因此,如果您已经推送了任何可以到达ABMC的引用,则可能需要进行一些清理(请参阅"从上游重定基恢复"下的rebase文档)。
如果你想要MC的版本,那么问题就很多了,不是说你得不到,而是我不认为你做一个rebase就能得到;并且MC也将是"有害合并",这也可能导致与将来的rebase尝试有关的问题(尤其)。
默认情况下,rebase会尝试生成线性历史记录,而不会生成合并提交。您可以使用--preserve-merges选项让它生成合并提交,但这与-i的交互效果不佳(如果您试图通过这样做来修改合并,我预计可能会出现几个问题)。
如果你不担心在合并提交中隐藏修改的问题,并且真的想产生一个类似MC的提交,那么方法是:
首先,将master ref移回M,同时保留索引中C的变更。

git checkout master
git reset --soft HEAD^

然后将更改直接重新应用于合并提交

git commit --amend
lsmepo6l

lsmepo6l2#

正如公认的答案所说,git rebase -i(aka --interactive)支持一个额外的选项-p(aka --preserve-merges)。然而,与公认的答案不同的是,我想指出的是,这实际上似乎可以很好地达到预期的结果,因此,如果您执行git rebase -i -p HEAD~2,合并提交将出现在交互式rebase文件中:

pick abcdeff Merge branch 'feature' into develop
pick abcdefc Extra changes

现在你可以编辑这个重定基文件来标记第二次提交,并完成重定基。看起来一切都很好。
但是,我不明白为什么git文档警告不要使用-i -p(在某些版本的文档中,但不是所有版本的文档中,-p都被弃用了),所以你的里程可能会有所不同。看起来主要的问题是在使用this时试图重新排序提交时出现的...所以不要这样做!
建议使用-p选项的替代选项似乎是git rebase -i -r;但这会产生一个非常长且复杂的交互式rebase文件,它看起来与我所期望的完全不同(即上面所示的简单rebase文件)。
如果有人能给出一个答案,详细解释git rebase -i -p在这种情况下是否合适以及为什么合适,那将是非常有帮助的。

相关问题