1

目前我有一个1-user-model分支。

然后,我从这里签出并创建了一个1-user-model-squash分支。

然后,当我尝试运行时git merge --squash 1-user-model,出现此错误。

致命的:您不能将 --squash 与 --no-ff 结合使用。

我还尝试签出master然后运行相同的命令,但仍然出现该错误。

有什么线索吗?

4

1 回答 1

1

您不能合并的原因--no-ff--squash壁球合并不是合并。

壁球合并不是合并!

我知道这听起来很奇怪而且是错误的。而且,更糟糕的是,当你在运行的过程git merge --squash,你正在合并。

结果不是“合并”

怎么会这样?合并的行为如何导致不是合并的结果?

在某种程度上,这是一个术语问题。Git 使用merge作为动词,表示合并某些代码更改的动作,并作为形容词,表示特定类型的提交:合并提交。人们——包括我——把这个形容词形式缩短为“a merge”,把它变成一个名词。

你得到的提交git merge --squash不是合并提交

在Git 中,合并提交是至少包含两个父提交的提交。

这就是合并提交的定义。它清晰而简单。这意味着在未来,当人们——也许是你自己,也许是其他人——正在查看这个存储库中随着时间推移发生的事情的历史,并且他们找到了提交时,他们将能够看到:“啊哈,这个提交是合并,它是通过合并这两个父提交来实现的。”

该命令git merge --squash不会做出这些提交之一。相反,它运行常规的合并代码,然后停止并强制您进行自己的提交,即使合并成功也是如此。当您进行该提交时,它是一个普通的、非合并的、单亲提交。

因此,git merge --squash可能会合并(代码),但不会产生合并。

同时,该--no-ff标志的意思是“进行合并”

如果您运行常规的非壁球类型,git mergeGit 有两个选项,其中一个仅有可用。Git 可以进行真正的合并,或者——如果真正的合并是微不足道的——它可以完全跳过合并并在当前分支名称上执行“快进”。

快进也不是合并

这是 Git 奇怪的术语阻碍的另一个地方。将其称为“快进合并”会适得其反:我们不仅没有得到合并提交,甚至没有得到任何合并操作。动词动作to merge永远不会发生,名词形容词“a merge”也不会产生。相反,我们只是得到一个沿着提交图前进的标签(分支名称)。1

无论如何,有时 Git可以进行简单的合并并快进标签,但您确实希望 Git 进行真正的合并。特别是,如果您将开发或功能线合并到发布或主分支中,您通常希望保持沿袭(提交历史)分开。快进操作会加入历史记录,而不是将它们分开。这就是为什么git mergehas --no-ff: 强制它进行真正的合并,即使 Git可以做一个假的并且只是快进分支。

--no-ff与 结合(或就此而言--ff-only)是没有意义的--squash,因为--squash这意味着“调用合并机制,但不进行提交,也不记录合并操作以供将来提交。” “壁球合并”——你在运行后所做的提交git merge --squash——不是合并提交。

简而言之,壁球合并不是合并。


1这种进步是你做一个时想要的git push,有时是成功后你想要的git fetch。如果您有一些上游分支,例如origin/master,并且其他人已经向上游添加了提交,那么您可以git fetch提交这些提交。然后,您通常希望在此基础上git rebase完成自己的工作,但如果您还没有自己的新工作,您可以简单地快进您的master.

执行此操作的命令是git merge,这很烦人,因为如果您确实有自己的工作,您可能应该使用git rebase. git rebase幸运的是,无论如何你都可以运行;当您没有工作时,这对您的分支名称具有与快进合并相同的效果。

或者,您可以运行git merge --ff-only,它尝试快进,如果不可能,则失败。这有点长,所以我自己使用别名,git mff,其中m代表“合并”或“移动”,ff代表“快进”。我有第二个别名lin, 用于log/look-at what is incoming。制作这两个别名非常简单:

git config --global alias.lin "log ..@{u}"
git config --global alias.mff "merge --ff-only"

现在我可以运行git fetch,然后git lin看看有什么,然后git mff如果我只需要快进到那个,或者git show特别有趣的部分,创建一个新的分支和/或git rebase如果有必要,等等。

于 2016-06-16T21:28:27.077 回答