67

一个成功的 Git 分支模型建议--no-ff在合并分支时使用:

--no-ff标志会导致合并始终创建一个新的提交对象,即使可以使用快进执行合并。这样可以避免丢失有关功能分支的历史存在的信息,并将所有添加该功能的提交组合在一起。[…]

是的,它会创建更多(空)提交对象,但收益比成本要大得多。不幸的是,我还没有找到一种方法来实现--no-ffgit merge 的默认行为,但它确实应该是。

但是,了解 Git 工作流程建议不要使用--no-ff

所以你添加了一条新规则:“当你在你的特性分支中合并时,使用 –-no-ff来强制一个新的提交。” 这样就完成了工作,然后您继续前进。[…]

--no-ff创可贴、破损bisectblame谜团都是你把螺丝刀当锤子的征兆。[…]

对于不同的场景,这两种方法似乎都是合理的,但什么被认为是“好的做法”?

什么时候用--no-ff,什么时候不用,为什么?

4

3 回答 3

50

这真的取决于你想要做什么。我的经验法则是,如果合并“意味着什么”,我会使用该--no-ff选项。当合并实际上没有任何意义并且您可能使用了变基时,没有理由使用--no-ff.

git 的特点是它是一个非常强大的工具,您可以通过多种方式使用它——其中大部分都没有错。问什么是“正确的方式”去做这件事就像问什么是画一幅画的正确方式。

至少对我来说,这是我喜欢的一套不断发展的方式,团队中经常讨论我们希望如何在代码上进行协作——由此我们试图得出一种“这里是如何完成的”标准,但是这只是我们的做法。

于 2013-08-08T14:02:44.120 回答
49

对于具有单个提交的已完成分支的情况,不要使用--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 次提交实际上属于一个特性吗?

于 2013-08-08T14:24:31.433 回答
4

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

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

在这种情况下,分支的存在只是为了让不同的开发人员工作而不会发生冲突,当特性完成后,它们需要合并到 master 中,而知道这些特性是否在不同的分支中实现并不重要。

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

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

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

在评论之后,我更喜欢rebase, 和pull --rebase工作流程。

于 2013-08-08T13:25:32.427 回答