何时在Git中使用'--no-ff'合并选项

时间:2013-08-08 12:41:01

标签: git git-merge fast-forward

A Successful Git Branching Model建议在合并分支时使用--no-ff

  

--no-ff标志使合并始终创建新提交   对象,即使可以使用快进执行合并。这个   避免丢失有关特征历史存在的信息   分支和组合所有提交,共同添加   特征。 [...]

     

是的,它会创建一些(空的)提交对象,但增益是   这个成本要大得多。不幸的是,我还没有找到办法   make --no-ff git merge的默认行为,但确实如此   应该是。

Understanding the Git Workflow但是,建议使用--no-ff

  

因此,您添加了一条新规则:“在功能分支中合并时,请使用   –-no-ff强制进行新的提交。“这可以完成工作,然后移动   上。 [...]

     

--no-ff创可贴,破碎的bisectblame谜团都是   您使用螺丝刀作为锤子的症状。 [...]

这两种方法对于差异情景似乎都是合理的,但什么被认为是“良好做法?”

您何时使用--no-ff,何时不使用,为什么?

3 个答案:

答案 0 :(得分:44)

这真的取决于你想要做什么。我的经验法则是,如果合并“意味着什么”,我使用--no-ff选项。如果合并没有任何意义,你可能已经使用了rebase,那么就没有理由使用--no-ff

使用git的东西是它是一个非常强大的工具,你可以在很多方面使用它 - 其中大多数没有错。询问做什么的“正确方法”就像问什么是绘制图片的正确方法。

至少对我来说,这是我喜欢的一系列不断变化的方式,在团队中经常讨论我们如何在代码上进行协作 - 从中​​我们试图得出一种“如何在这里完成”标准,但这只是我们的方式。

答案 1 :(得分:43)

对于具有单个提交的已完成分支的情况,请不要使用--no-ff,只需快进它,因为历史记录将更简单,更简洁。很难说--no-ff在这种情况下会给你带来任何好处,因为只用一次提交就可以看到开发的并行分支,而不是连续行中的单个提交,这是无趣的:

# No fast-forward
$ git merge --no-ff awesome-feature
*   3aa649c Merge branch 'awesome-feature'
|\
| * 35ec88f Add awesome feature
|/
* 89408de Modify feature-001.txt and fix-001.txt
* c1abcde Add feature-003

# versus fast-forward
$ git merge awesome-feature
* 35ec88f Add awesome feature
* 89408de Modify feature-001.txt and fix-001.txt
* c1abcde Add feature-003

对于具有多个提交的已完成分支的情况,由您决定是否要保持分支开发发生在并行和顺序中的事实。我可能会使用--no-ff进行多次提交,这样我就可以在视觉上看到这个分支的工作,以便我可以使用单个git revert -m 1 <sha-of-merge-commit>轻松操作它,如果必须的话。

# No fast-forward
$ git merge --no-ff epic-feature
*   d676897 Merge branch 'epic-feature'
|\
| * ba40d93 Add octocat.txt
| * b09d343 Add bye.txt
| * 75e18c8 Add hello.txt
|/
* 89408de Modify feature-001.txt and fix-001.txt
* c1abcde Add feature-003

# versus fast-forward
$ git merge epic-feature
* ba40d93 Add octocat.txt
* b09d343 Add bye.txt
* 75e18c8 Add hello.txt
* 89408de Modify feature-001.txt and fix-001.txt
* c1abcde Add feature-003

在这种快速合并的情况下,如果没有提交消息本身的附加信息,很难说最后3次提交实际上属于一个特征?

答案 2 :(得分:2)

这实际上取决于您的工作流程以及您如何使用分支机构。

假设您正在开发中有一个“主”和两个功能分支“foo”和“bar”。

在这种情况下,仅存在分支以允许不同的开发人员工作而不会发生冲突,当功能完成时,它们需要合并到主服务器中,并且知道这些功能是否在不同的分支中实现并不重要。 / p>

但是你可以拥有不同的工作流程,分支机构“foo”和“bar”指的是你系统中的独立模块。

在这种情况下,某些提交可能会更改模块范围之外的文件。当您将这两个分支合并到主服务器时,特定模块之外的文件日志可能会变得混乱,并且很难知道这些更改的来源。

您需要确定分支合并的历史记录对您的工作流程是否重要。

根据评论,我更喜欢rebasepull --rebase工作流程。