git merge 和 git merge --no-ff 有什么区别?

使用gitk log ,我无法发现两者之间的差异。如何观察差异(使用 git 命令或某些工具)?

答案

如果--no-ff标志检测到您当前的HEAD是您要合并的提交的祖先,则可以防止git merge执行 “快进”。快进是指 git 只是移动分支指针以指向传入的提交,而不是构造合并提交。这通常发生在进行git pull而没有任何本地更改的情况下。

但是,有时您想防止这种行为的发生,通常是因为您想要维护特定的分支拓扑(例如,您正在合并一个主题分支,并且希望确保在阅读历史记录时它看起来像这样)。为此,您可以传递--no-ff标志,并且git merge始终构造一个合并,而不是快速转发。

类似地,如果您要执行git pull或使用git merge以便显式快进,并且如果它无法快进--ff-only纾困,则可以使用--ff-only标志。这样,您可以不加考虑地定期执行诸如git pull --ff-only ,然后,如果出错,则可以返回并确定是否要合并或重新设置基础。

git checkout -b contact-form
(do your work on "contact-form")
git status
git commit -am  "updated form in contact module"
git checkout master
git merge --no-ff contact-form
git branch -d contact-form
git push origin master
$ git status
# On branch master
# Changed but not updated:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   ecc/Desktop.php
#       modified:   ecc/Mobile.php
#       deleted:    ecc/ecc-config.php
#       modified:   ecc/readme.txt
#       modified:   ecc/test.php
#       deleted:    passthru-adapter.igs
#       deleted:    shop/mickey/index.php
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       ecc/upgrade.php
#       ecc/webgility-config.php
#       ecc/webgility-config.php.bak
#       ecc/webgility-magento.php
$ git checkout -b ecc
$ git add ecc/*
$ git reset HEAD passthru-adapter.igs
$ git reset HEAD shop/mickey/index.php
Unstaged changes after reset:
M       passthru-adapter.igs
M       shop/mickey/index.php

$ git commit -m "Webgility ecc desktop connector files; integrates with Quickbooks"

$ git checkout master
D       passthru-adapter.igs
D       shop/mickey/index.php
Switched to branch 'master'
$ git merge --no-ff ecc
$ git branch -d ecc
Deleted branch ecc (was 98269a2).
$ git push origin master
Counting objects: 22, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (14/14), done.
Writing objects: 100% (14/14), 59.00 KiB, done.
Total 14 (delta 10), reused 0 (delta 0)
To git@github.com:me/mywebsite.git
   8a0d9ec..333eff5  master -> master

--no-ff选项确保不会发生快速向前合并,并且始终将创建一个新的提交对象 。如果您希望 git 维护功能分支的历史记录,则可能需要这样做。 git merge --no-ff和git merge在上图中,左侧是使用git merge --no-ff之后的 git 历史的示例,右侧是使用 ff merge 可以使用的git merge的示例。

编辑 :此图像的先前版本仅指示合并提交的单亲。 合并提交有多个父提交 ,git 用来维护 “功能分支” 和原始分支的历史记录。多个父链接以绿色突出显示。

合并策略

显式合并 :创建一个新的合并提交。 (如果使用--no-ff这将是您得到的。)

在此处输入图片说明

快速转发合并:快速转发 ,而无需创建新的提交:

在此处输入图片说明

调整基准:建立新的基准级别:

在此处输入图片说明

壁球:挤压或挤(东西)与力,使其变得平坦:

在此处输入图片说明

这是一个老问题,在其他帖子中也对此进行了微妙的提及,但对我来说,单击此按钮的原因是, 非快进合并将需要单独的 commit

--no-ff 标志使合并始终创建一个新的提交对象,即使合并可以通过快进来执行。这样可以避免丢失有关要素分支历史存在的信息,并将所有添加了要素的提交分组在一起