When to use the '--no-ff' merge option in Git

非 Y 不嫁゛ 提交于 2019-11-28 16:03:43
Tomas

It's really dependent on what you're trying to do. My rule of thumb is that if the merge "means something" I use the --no-ff option. When the merge doesn't really mean anything and you might have used a rebase there's no reason to use --no-ff

The thing with git is that it's a very powerful tool, and you can use it in many ways - most of which are not wrong. Asking what's the "right way" to do it is like asking what's the right way to paint a picture.

At least for me it's an evolving set of ways I like to do it, with frequent discussions in the team of how we want to collaborate on the code - from this we try to derive a kind of "how it's done here" standard, but it's just our way of doing it.

For the case of a finished branch with a single commit, don't use --no-ff, just fast-forward it, because the history will be much simpler and less cluttered. It's hard to argue that --no-ff gets you any advantages in this case, because it's uninteresting to see a parallel branch of development with just a single commit, vs a single commit in a sequential line:

# 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

For the case of a finished branch with more than a single commit, it's up to you, whether or not you want to keep the fact that the branched development happened in parallel vs sequential. I would probably use --no-ff for more than one commit, just so that I can visually see this branched work, and so that I can manipulate it easily with a single git revert -m 1 <sha-of-merge-commit> if I had to.

# 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

See how in this case of fast-forward merge, without additional information in the commit messages themselves, it's hard to tell that the last 3 commits actually belong together as one feature?

That really depends on your workflow, and how you are using branches.

Let´s say you have a "master" and two feature branches, "foo" and "bar", in development.

In this case, the branches only exist to allow different developer work without conflict, when the features are done, they need to be merged into master, and it is not important to know if those features were implemented in different branches.

But you could have a different workflow, were the branches, "foo" and "bar", refers to independent modules in your system.

In this case, some commits may change files outside the module scope. When you merge those two branches to the master, the log of the files, outside the specific module, may become confusing and hard to know where those changes come from.

You need to decide if the historic of branch´s merge is important to your workflow.

And following the comments, I prefer the rebase, and pull --rebase workflow.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!