Git branch - Why does git fast-forward merges by default

De openkb
Aller à : Navigation, rechercher

Sommaire

Questions

Coming from mercurial, I use branches to organize features. Naturally, I want to see this work-flow in my history as well.

I started my new project using git and finished my first feature. When merging the feature, I realized git uses fast-forward, i.e. it applies my changes directly to the master branch if possible and forgets about my branch.

So to think into the future: I m the only one working on this project. If I use git s default approach (fast-forward merging), my history would result in one giant master branch. Nobody knows I used a separate branch for every feature, because in the end I ll have only that giant master branch. Won t that look unprofessional?

By this reasoning, I don t want fast-forward merging and can t see why it is the default. What s so good about it?

Answers

http://nvie.com/posts/a-successful-git-branching-model/ http://nvie.com/posts/a-successful-git-branching-model/

https://sandofsky.com/blog/git-workflow.html https://sandofsky.com/blog/git-workflow.html

<img src="https://i.stack.imgur.com/vRdkr.png" alt="alt text">
http://nvie.com/posts/a-successful-git-branching-model/ http://nvie.com/posts/a-successful-git-branching-model/

Incorporating a finished feature on develop Finished features may be merged into the develop branch to add them to the upcoming release:
$ git checkout develop
Switched to branch  develop 
$ git merge --no-ff myfeature
Updating ea1b82a..05e9557
(Summary of changes)
$ git branch -d myfeature
Deleted branch myfeature (was 05e9557).
$ git push origin develop
The --no-ff flag causes the merge to always create a new commit object, even if the merge could be performed with a fast-forward. This avoids losing information about the historical existence of a feature branch and groups together all commits that together added the feature.

http://git-scm.com/docs/git-config http://git-scm.com/docs/git-config

By default, Git does not create an extra merge commit when merging a commit that is a descendant of the current commit. Instead, the tip of the current branch is fast-forwarded.
When set to false, this variable tells Git to create an extra merge commit in such a case (equivalent to giving the --no-ff option from the command line).
When set to only , only such fast-forward merges are allowed (equivalent to giving the --ff-only option from the command line).

The fast-forward is the default because:

    • short-lived branches are very easy to create and use in Git
    • short-lived branches often isolate many commits that can be reorganized freely within that branch
    • those commits are actually part of the main branch: once reorganized, the main branch is fast-forwarded to include them.

But if you anticipate an iterative workflow on one topic/feature branch (i.e., I merge, then I go back to this feature branch and add some more commits), then it is useful to include only the merge in the main branch, rather than all the intermediate commits of the feature branch.

http://sip-router.org/wiki/git/gitconfig http://sip-router.org/wiki/git/gitconfig

[branch "master"]
# This is the list of cmdline options that should be added to git-merge 
# when I merge commits into the master branch.

# The option --no-commit instructs git not to commit the merge
# by default. This allows me to do some final adjustment to the commit log
# message before it gets commited. I often use this to add extra info to
# the merge message or rewrite my local branch names in the commit message
# to branch names that are more understandable to the casual reader of the git log.

# Option --no-ff instructs git to always record a merge commit, even if
# the branch being merged into can be fast-forwarded. This is often the
# case when you create a short-lived topic branch which tracks master, do
# some changes on the topic branch and then merge the changes into the
# master which remained unchanged while you were doing your work on the
# topic branch. In this case the master branch can be fast-forwarded (that
# is the tip of the master branch can be updated to point to the tip of
# the topic branch) and this is what git does by default. With --no-ff
# option set, git creates a real merge commit which records the fact that
# another branch was merged. I find this easier to understand and read in
# the log.

mergeoptions = --no-commit --no-ff

The OP adds in the comments:

I see some sense in fast-forward for [short-lived] branches, but making it the default action means that git assumes you... often have [short-lived] branches. Reasonable?

Jefromi answers:

I think the lifetime of branches varies greatly from user to user. Among experienced users, though, there s probably a tendency to have far more short-lived branches. To me, a short-lived branch is one that I create in order to make a certain operation easier (rebasing, likely, or quick patching and testing), and then immediately delete once I m done.
That means it likely should be absorbed into the topic branch it forked from , and the topic branch will be merged as one branch. No one needs to know what I did internally in order to create the series of commits implementing that given feature.

More generally, I add:

http://stackoverflow.com/questions/216212#216228 http://stackoverflow.com/questions/216212#216228
    *if it is linear, one branch makes sense. *If you need to isolate features and work on them for a long period of time and repeatedly merge them, several branches make sense.

http://stackoverflow.com/questions/2100829/when-should-you-branch/2107672#2107672 http://stackoverflow.com/questions/2100829/when-should-you-branch/2107672#2107672

http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/ http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/ http://stackoverflow.com/questions/1598759/git-and-mercurial-compare-and-contrast/1599930#1599930 http://stackoverflow.com/questions/1598759/git-and-mercurial-compare-and-contrast/1599930#1599930

Mercurial, by default, uses anonymous lightweight codelines, which in its terminology are called "heads".
Git uses lightweight named branches, with injective mapping to map names of branches in remote repository to names of remote-tracking branches.
http://stackoverflow.com/questions/3965676/why-did-git-detach-my-head/3965714#3965714 http://stackoverflow.com/questions/3965676/why-did-git-detach-my-head/3965714#3965714

Source

License : cc by-sa 3.0

http://stackoverflow.com/questions/2850369/why-does-git-fast-forward-merges-by-default

Related

Outils personnels
Espaces de noms

Variantes
Actions
Navigation
Outils