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

user1162226 878 git merge fast-forward

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

Lily Ballard.. 989

如果--no-ff标志git merge检测到您当前HEAD是您尝试合并的提交的祖先,则该标志会阻止执行"快进" .快进是指git只是将您的分支指针移动到指向传入提交的位置,而不是构建合并提交.这通常发生在git pull没有任何本地更改的情况下.

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

同样,如果你想执行一个git pull或者使用git merge以便明确地快进,并且你想要在它不能快进时挽救,那么你可以使用该--ff-only标志.通过这种方式,您可以不git pull --ff-only经思考地定期执行某些操作,然后如果错误,您可以返回并决定是否要合并或重新绑定.

  • 为了更直接地回答OP的问题:它们并不总是不同,但如果它们是,从`gitk`或`git log --graph`可以清楚地看出快进合并没有创建合并提交,而非快进的一个. (81认同)
  • 扩展避免ff的原因会很好:作者提到"特定分支拓扑"意味着在--no-ff情况下,额外的合并提交用作合并的标记.专业人员是明确的合并标记,包含作者和合并的名称.缺点是非线性历史,看起来像一组融合的铁轨.合并的可能的*心理*副作用虽然是由于更长的审查过程而导致兴趣失去兴趣:http://blog.spreedly.com/2014/06/24/merge-pull-request-considered-harmful/#. Vf2oMyBVikp (11认同)
  • @merlinpatt当然.如果你在GitHub中合并一个pull请求,它就相当于`--no-ff`. (9认同)
  • 从开发或开发到master的功能中的`--no-ff`类似于合并pull请求是否公平? (6认同)

Chris K.. 950

图形答案这个问题

这是一个有明确解释和使用图形说明的网站git merge --no-ff:

git merge --no-ff和git merge之间的区别

直到我看到这个,我完全迷失了git.使用--no-ff允许某人查看历史记录以清楚地看到您签出的分支机构.(该链接指向github的"网络"可视化工具)这是另一个有插图的精彩参考.这个参考文章很好地补充了第一个,更多地关注那些不熟悉git的人.


像我这样的新手的基本信息

如果你像我一样,而不是Git-guru,我在这里的答案描述了处理从git跟踪中删除文件而不从本地文件系统中删除文件,这似乎记录不清,但经常发生.另一个新情况是获得当前的代码,仍然设法逃避我.


示例工作流程

我将一个软件包更新到我的网站,不得不回到我的笔记中查看我的工作流程; 我认为在这个答案中添加一个例子很有用.

我的git命令工作流程:

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非常冗长.

$ 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

请注意以上3项内容:
1)在输出中,您可以看到ECC包升级的更改,包括添加新文件.
2)另请注意,/ecc我删除了两个独立于此更改的文件(不在文件夹中).ecc我不会将这些文件删除混淆,而是稍后会创建一个不同的cleanup分支来反映这些文件的删除.
3)我没有按照我的工作流程!当我试图让ecc再次工作时,我忘记了git.

下面:而不是git commit -am "updated ecc package"我通常会做的全包,我只想在文件/ecc夹中添加文件.那些删除的文件并不是我的特定部分git add,但因为它们已经在git中被跟踪,我需要将它们从这个分支的提交中删除:

$ 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



用于自动执行上述操作的脚本

在一天中使用过程10次以上,我已经开始编写批处理脚本来执行命令,所以我做了一个几乎正确的git_update.sh <branch> <"commit message">脚本来执行上述步骤.这是该脚本的Gist源代码.

而不是git commit -am我从通过生成的"修改"列表中选择文件git status,然后粘贴在此脚本中的文件.这是因为我做了几十次编辑,但想要不同的分支名称来帮助分组更改.

  • @DesignerGuy是的,你可以安全地删除旧分支.将分支es视为指向特定提交的指针. (13认同)
  • 在与`--no-ff`选项合并后,你还能安全地删除分支吗? (11认同)
  • 我发现链接页面中的这个文本很有用:没有--no-ff"从Git历史中看不到哪些提交对象一起实现了一个功能 - 你必须手动读取所有日志消息." (2认同)

Daniel Smith.. 200

--no-ff选项确保不会发生快进合并,并始终创建新的提交对象.如果您希望git维护功能分支的历史记录,这可能是理想的.             git merge --no-ff vs git merge 在上面的图像中,左侧是使用后的git历史git merge --no-ff的示例,右侧是可以使用git mergeff合并的示例.

编辑:此图像的先前版本仅指示合并提交的单个父项.合并提交有多个父提交,git用它来维护"特征分支"和原始分支的历史记录.多个父链接以绿色突出显示.

  • 绿色箭头表示提交与父项之间的链接,其中提交具有多个父项.正常提交(黑色)只有一个父级. (10认同)
  • @DanielSmith你如何绘制这个优雅的图形? (8认同)
  • @chancyWu与Adobe Illustrator (3认同)
  • 绿色箭头表示与黑色箭头的对比是什么? (2认同)

Premraj.. 166

合并策略

  • 显式,非快进合并
  • 隐式通过rebase或快进合并
  • 壁球合并

在此输入图像描述

在此输入图像描述

在此输入图像描述

在此输入图像描述

  • 第一个是"显式合并",标题为"合并",是非合并的. (17认同)
  • 有趣的图形,但它并没有真正显示--no-ff的情况,因此在这里没有完全回答这个问题 (8认同)
  • 那么Rebase和快进合并之间有什么区别? (3认同)

Parris Varne.. 34

这是一个老问题,这在其他帖子中有点巧妙地提到,但是对我来说这个点击的解释是非快进合并将需要单独的提交.

  • @ChrisK`git merge --no-ff ecc`你只需在分支主机的`git log`中有一个额外的合并提交.从技术上讲,如果master指向commit ecc的直接祖先,则不需要,但是通过指定--no-ff选项,您将强制创建该合并提交.它将有标题:`合并分支'ecc'` (2认同)

归档时间:

查看次数:

420044 次

最近记录:

4 月,3 周 前