默认转发合并?

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

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

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

通过这个推理,我不想快速前进合并,也不知道为什么它是默认的。 这有什么好处?


快速合并对于短期分支是有意义的,但在更复杂的历史中,非快速合并可能会使历史更易于理解,并使恢复一组提交更容易。

警告 :非快速转发也有潜在的副作用。 请查看https://sandofsky.com/blog/git-workflow.html,避免“无-FF”以其“检查点犯下”那个破平分或指责,并认真考虑是否应作为默认的做法master

替代文字
(来自nvie.com,Vincent Driessen,发表“ 一个成功的Git分支模型 ”)

在开发中加入完成的功能

完成的功能可以合并到开发分支中,将它们添加到即将发布的版本中:

$ 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标志会导致合并始终创建一个新的提交对象,即使合并可以用快进执行。 这样可以避免丢失关于功能分支历史存在的信息,并将所有提交的功能组合在一起。

JakubNarębski也提到了配置merge.ff

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


快进是默认的,因为:

  • 短命的分支非常容易在Git中创建和使用
  • 短命的分支往往孤立许多可以在该分支内自由重组的提交
  • 这些提交实际上是主要分支的一部分:一旦重新组织,主要分支被快速转发以包括它们。
  • 但是,如果您预计在一个主题/功能分支上有一个迭代工作流程(即我合并,然后返回到此功能分支并添加更多提交),那么仅在主分支中包含合并而非特征分支的所有中间提交。

    在这种情况下,您最终可能会设置这种配置文件:

    [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在评论中增加了:

    我发现快速转发[短命]分支有一定意义,但将其设置为默认操作意味着git假定您经常有[短命]分支。 合理?

    Jefromi回答:

    我认为分支机构的生命周期因用户而异。 然而,在有经验的用户中,可能存在更多短命分支的趋势。

    对我而言, 一个短命的分支是我为了使某个操作更容易 (重新绑定,可能或快速修补和测试)而创建的分支 ,然后在完成后立即删除。
    这意味着它可能应该被吸收到它所分出的主题分支中 ,并且主题分支将被合并为一个分支。 没有人需要知道我在内部做了什么,才能创建实现该特定功能的一系列提交。

    更一般地,我补充说:

    这取决于你的开发流程:

  • 如果它是线性的,则一个分支是有意义的。
  • 如果您需要隔离功能并长时间工作并反复合并它们,则有几个分支是有意义的。
  • 请参阅“ 什么时候分支?

    实际上,当您考虑Mercurial分支模型时,它的核心是每个存储库一个分支(即使您可以创建匿名头部,书签甚至命名分支)
    请参阅“Git和Mercurial - 比较和对比”。

    默认情况下,Mercurial使用匿名轻量级代码行,其术语称为“头”。
    Git使用轻量级命名分支,使用内射映射将远程存储库中分支的名称映射到远程跟踪分支的名称。
    Git“强迫”你命名分支(除了一个未命名的分支,这是一种称为“分离HEAD”的情况),但我认为这适用于分支繁重的工作流程,如主题分支工作流程,含义单个存储库范例中的多个分支。


    让我对VonC非常全面的回答进行一些扩展:


    首先,如果我没有记错,事实上Git默认情况下不会在快速前进的情况下创建合并提交,这来自考虑单分支“相同的存储库”,其中使用互拉来同步这两个存储库(a工作流程,您可以在大多数用户文档中找到第一个示例,包括“The Git User's Manual”和“Version Control by Example”)。 在这种情况下,您不使用pull来合并完全实现的分支,而是使用它来跟上其他工作。 当您碰巧执行保存并存储在存储库中的同步时,您不希望出现短暂且不重要的事实,并且保存将来。

    请注意,功能分支和单个存储库中具有多个分支的实用性仅在后来才出现,具有更广泛的VCS使用和良好的合并支持,并尝试各种基于合并的工作流程。 这就是为什么例如Mercurial最初只支持每个存储库一个分支(加上跟踪远程分支的匿名提示)的原因,正如旧版“Mercurial:权威指南”中所见。


    二,以下使用功能分支最佳做法时,即有分支机构都应该从稳定版(通常从最后一个版本),开始能够樱桃挑选和选择哪些功能通过选择功能分支合并, 包括通常不处于快进状态 ......这使得这个问题没有实际意义。 您需要担心创建真正的合并,而不是在合并第一个分支时快进(假设您不直接在'master'上进行单提交更改); 所有其他后来的合并当然都是非快速前进的情况。

    HTH

    链接地址: http://www.djcxy.com/p/7833.html

    上一篇: forward merges by default?

    下一篇: Git fast forward VS no fast forward merge