为什么默认情况下git快进合并?

来自mercurial,我使用分支组织功能。
当然,我也想在我的历史上看到这个工作流程。

我使用git开始我的新项目并完成了我的第一个功能。当合并功能,我意识到git使用快进,即它应用我的更改直接到主分支,如果可能的话,忘记我的分支。

所以想想未来:我是唯一一个在这个项目上工作的人。如果我使用git的默认方法(快进合并),我的历史将导致一个巨大的主分支。
没有人知道我为每个功能使用一个单独的分支,因为最终我将只有那个巨大的主分支。这不会看起来不专业?

通过这个推理,我不想快速合并,不能明白为什么它是默认的。这是什么好?

最佳答案
快速合并对于短期分支是有意义的,但是在更多的complex history中,非快速合并可能使历史更容易理解,并且使得更容易恢复一组提交。

警告:非快进还具有潜在的副作用。请检查https://sandofsky.com/blog/git-workflow.html,避免’no-ff’与它的“检查点提交”,打破平分或责备,仔细考虑它是否应该是你的默认方法为主人。

(从nvie.comVincent Driessen,post“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.

Jakub Narębskimentions config merge.ff

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).

快进是默认值,因为:

>短暂的分支很容易在Git中创建和使用
>短期分支经常隔离许多可以在该分支内自由重组的提交
>那些提交实际上是主分支的一部分:一旦重组,主分支被快速转发以包括它们。

但是如果你预期一个主题/功能分支上的迭代工作流(即,我合并,然后我回到这个特性分支并添加一些更多的提交),那么在主分支中只包括合并是有用的,而不是所有中间提交的功能分支。

在这种情况下,您可以最终设置this kind of config file

[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

OP在评论中添加:

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回答:

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.

更一般来说,我补充说:

it really depends on your 07009:

  • 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.

See “070010”

实际上,当你考虑Mercurial分支模型,它的核心one branch per repository(即使你可以创建anonymous heads, bookmarks and even named branches)
“Git and Mercurial – Compare and Contrast”

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.
Git “forces” you to name branches (well, with the exception of a single unnamed branch, which is a situation called a “070014”), but I think this works better with branch-heavy workflows such as topic branch workflow, meaning multiple branches in a single repository paradigm.

转载注明原文:为什么默认情况下git快进合并? - 代码日志