为什么git默认执行快进合并? [英] Why does git perform fast-forward merges by default?

查看:87
本文介绍了为什么git默认执行快进合并?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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.

所以要思考未来:我是唯一从事此项目的人.如果我使用git的默认方法(快速合并),则我的历史记录将导致出现一个巨型master分支. 没人知道我为每个功能都使用了一个单独的分支,因为最后我将只有那个巨大的主分支.看起来不专业吗?

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?

推荐答案

快速合并对于短暂的分支有意义,但是在

Fast-forward merging makes sense for short-lived branches, but in a more complex history, non-fast-forward merging may make the history easier to understand, and make it easier to revert a group of commits.

警告:非快进也有潜在的副作用.请查看 https://sandofsky.com/blog/git-workflow.html ,避免带有检查点提交"的"no-ff"打破了对分或怪罪,并仔细考虑它是否应作为master的默认方法.

Warning: Non-fast-forwarding has potential side effects as well. Please review https://sandofsky.com/blog/git-workflow.html, avoid the 'no-ff' with its "checkpoint commits" that break bisect or blame, and carefully consider whether it should be your default approach for master.


(来自 nvie.com Vincent Driessen ,发布" A成功的Git分支模型 )


(From nvie.com, Vincent Driessen, post "A successful Git branching model")

在开发中加入已完成的功能

完成的功能可能会合并到developer分支中,以将其添加到即将发布的版本中:

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

--no-ff标志使合并始终创建一个新的提交对象,即使合并可以通过快进来执行.这样可以避免丢失有关要素分支历史存在的信息,并将所有添加了要素的提交分组在一起.

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.

JakubNarębski

默认情况下,当合并作为当前提交的后代的提交时,Git不会创建额外的合并提交.相反,当前分支的尖端是快进的.
设置为false时,此变量告诉Git在这种情况下创建一个额外的合并提交(等同于从命令行提供--no-ff选项).
设置为"only"时,仅允许这种快速合并(等同于从命令行提供--ff-only选项).

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:

  • 短期分支很容易在Git中创建和使用
  • 寿命短的分支通常会隔离许多可在该分支内自由重组的提交
  • 这些提交实际上是main分支的一部分:一旦重新组织,主要分支就会被快速转发以包含它们.

但是,如果您希望在一个主题/功能分支上进行迭代的工作流(即,我合并,那么我将返回该功能分支并添加更多提交),那么仅将合并包含在主分支中会很有用. ,而不是功能分支的所有中间提交.

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.

在这种情况下,您可以最终设置此类配置文件:

In this case, you can end up setting 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在注释中添加:


The OP adds in the comments:

我认为[short-lived]分支在某种意义上是快进的,但是将其设置为默认操作意味着git假设您...经常拥有[short-lived]分支.合理吗?

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

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.

一般来说,我补充:

这实际上取决于您的开发工作流程:

  • 如果它是线性的,则一个分支有意义.
  • 如果您需要隔离功能并长时间使用它们并重复合并它们,则可以使用多个分支.

请参阅" 何时应分支? "

See "When should you branch?"

实际上,当您考虑Mercurial分支模型时,它是其核心"Git和Mercurial-比较并对比" .

Actually, when you consider the Mercurial branch model, it is at its core one branch per repository (even though you can create anonymous heads, bookmarks and even named branches)
See "Git and Mercurial - Compare and Contrast".

默认情况下,Mercurial使用匿名的轻量级代码行,在其术语中称为"heads".
Git使用轻量级的命名分支,并通过注入式映射将远程存储库中的分支名称映射到远程跟踪分支的名称.
Git强迫"您命名分支(好吧,除了一个未命名的分支,这种情况称为"

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 "detached HEAD"), but I think this works better with branch-heavy workflows such as topic branch workflow, meaning multiple branches in a single repository paradigm.

这篇关于为什么git默认执行快进合并?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆