目前我有一个1-user-model
分支机构。
从这里开始,我检查并创建了一个1-user-model-squash
分支。
然后,当我尝试运行git merge --squash 1-user-model
时,我收到此错误。
致命:你无法将--squash与--no-ff结合使用。
我还尝试检查master
然后运行相同的命令,但仍然得到该错误。
任何线索?
答案 0 :(得分:1)
您无法将--no-ff
与--squash
合并的原因是壁球合并不是合并。
我知道这听起来很怪异和错误。更糟糕的是,当您进入运行git merge --squash
的过程中时, merg ing 。
结果不是“合并”。
这怎么可能?合并行为如何导致不合并的事情?
在某种程度上,这是一个术语问题。 Git使用 merge 作为动词,意味着合并一些代码更改的动作,以及作为形容词,意味着特定类型的提交:合并提交。人们 - 包括我 - 将这种形容词形式简化为“合并”,将其变成名词。
git merge --squash
获得的提交不是合并提交 Git中的合并提交是一个至少提交两次父提交的提交。
这是合并提交的定义。这很简单明了。这意味着在未来,当人们 - 也许是你自己,也许是其他人 - 正在查看这个存储库中随时间发生的事件的历史,并且他们找到提交时,他们将能够看到:“啊哈,这个提交是合并,它是通过合并这两个父提交来实现的。“
命令git merge --squash
不会进行其中一次提交。相反,它运行常规合并代码,然后停止并强制您进行自己的提交,即使合并成功。当你做这个提交时,它是一个普通的,非合并的单父提交。
因此,git merge --squash
可以合并(代码),但它不会生成合并。
--no-ff
标志表示“进行合并”如果你运行常规的非壁球式git merge
,Git有两个选项,其中一个只有有时可用。 Git可以进行真正的合并,或者 - 如果真正的合并将是微不足道的 - 它可以完全跳过合并并在当前分支名称上执行“快进”。
这是Git奇怪的术语阻碍的另一个地方。将此称为“快进合并”会适得其反:我们不仅没有得到合并提交,我们甚至没有得到任何合并动作。动词动作合并,永远不会发生,并且不会产生名词形容词“合并”。相反,我们只是在提交图上获得一个标签(分支名称)。 1
在任何情况下,有时Git 可以进行简单的合并而只是快进标签,但你确实希望Git进行真正的合并。特别是,如果要将开发或功能行合并到发行版或主分支中,通常需要将沿袭(提交历史)分开。快进操作加入历史记录,而不是将它们分开。这就是为什么git merge
有--no-ff
:强制它进行真正的合并,即使Git 可以做一个假的,只是快进分支。
将--no-ff
(或者,就此而言,--ff-only
)与--squash
结合起来是没有意义的,因为--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
,等等。