如何使用正常提交压缩合并提交?

时间:2017-12-19 13:43:07

标签: git github merge commit squash

commit b0e5db36ed68d4562275adeb08001b1316a4da52
Merge: ea38baa 8220bb1

commit ea38baa3f46a48722987b8dd3892d2b8d81c4d1a

在这种情况下,如何压缩这两个提交

我正在使用

git rebase -i HEAD~2

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

2 个答案:

答案 0 :(得分:1)

这里要考虑两个因素:

首先,在某些方面rebase并不总是与合并提交很好。我会回到那几次。

其次,你所期待的结果并不完全清楚。如果你现在有类似

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

你想结束

吗?
x -- x -- ABC <--(master)

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

如果您希望版本为ABC,则非常简单。虽然M没有出现在rebase的TODO列表中,但所有通过 M进入主线的提交(即A和{这个例子中的{1}}是。所以只需将BB标记为“壁球”。唯一要记住的是这是历史重写,所以如果你已经推送了任何可以达到CABM的引用,那么可能需要清理(参见“从上游rebase中恢复”下的C文档)。

如果您希望版本为rebase,则会出现很多问题。并不是说你无法得到它,但我认为你不能通过MC得到它;而且,rebase将是一个“邪恶的合并”,这可能会导致未来MC尝试出现问题(等等)。

默认情况下,rebase会尝试生成线性历史记录,但不会生成合并提交。您可以使用rebase选项生成合并提交,但这与--preserve-merges不能很好地交互(如果您尝试通过执行此操作来修改合并,我预计会出现几个可能的问题)。

如果您不担心隐藏合并提交中的更改的问题,并且确实想要生成-i之类的提交,那么执行此操作的方法是:

首先,将MC引用移回master,同时保持索引中M的更改。

C

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

git checkout master
git reset --soft HEAD^

答案 1 :(得分:0)

正如接受的答案所说,git rebase -i(又名--interactive)支持附加选项-p(又名--preserve-merges)。但是,与接受的答案不同,我想指出的是,这实际上可以很好地实现所需的准确结果,因此,如果您执行git rebase -i -p HEAD~2,则合并提交将出现在交互式rebase文件中:

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

现在,您可以编辑此变基文件,以标记第二个提交以进行压缩并完成变基。一切似乎都很好。

但是,我不明白为什么git文档warns against using using -i -p(有些(但不是全部)版本说明-p已过时)的复杂性,因此您的工作量可能会有所不同。似乎主要问题是在尝试重新排序使用此命令时显示的提交时出现的,所以请不要这样做!

建议不要使用的-p选项似乎是git rebase -i -r;但这会产生一个非常长且复杂的交互式rebase文件,看起来根本不像我期望的那样(即,如上文本所示的简单rebase文件)。

如果任何人都可以添加答案,以详细说明git rebase -i -p在这种情况下是否可行以及为何如此,那将非常有帮助。