为什么 git 默认执行快进合并?
来自 Mercurial,我使用分支来组织功能。 当然,我也希望在我的历史中看到这个工作流程。
我使用 git 开始了我的新项目并完成了我的第一个功能。当合并该功能时,我意识到 git 使用快进,即如果可能的话,它会将我的更改直接应用到主分支,并忘记我的分支。
所以展望未来:我是唯一一个从事这个项目的人。如果我使用 git 的默认方法(快进合并),我的历史记录将产生一个巨大的主分支。 没有人知道我为每个功能使用了单独的分支,因为最终我将只有那个巨大的主分支。这样不会显得不专业吗?
根据这个推理,我不想快进合并,也不明白为什么它是默认的。它有什么好呢?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
快进合并对于短期分支有意义,但在更复杂的情况下历史,非快进合并可能会使历史更容易理解,并且更容易恢复一组提交。
警告:非快进也有潜在的副作用。请查看 https://sandofsky.com/workflow/git-workflow/,避免'no-ff' 及其“检查点提交”会破坏平分或责备,并仔细考虑它是否应该成为
master
的默认方法。(来自 nvie.com,文森特·德里森,帖子“< strong>成功的 Git 分支模型")
Jakub Narębski 还 提及 配置
merge.ff
:快进是默认设置,因为:
但是,如果您预期在一个主题/功能分支上有一个迭代工作流程(即,我合并,然后返回到该功能分支并添加更多提交),那么仅在主分支中包含合并而不是包含合并会很有用。功能分支的所有中间提交。
在这种情况下,您最终可以设置这种配置文件:
OP添加在评论中:
杰弗罗米回答:
更一般地说,我补充说:
请 ,当您考虑 Mercurial 分支模型时,它是其核心 每个存储库一个分支(即使您可以创建匿名头、书签甚至命名分支)
请参阅“Git 和 Mercurial - 比较和对比”。
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.
Warning: Non-fast-forwarding has potential side effects as well. Please review https://sandofsky.com/workflow/git-workflow/, 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
.(From nvie.com, Vincent Driessen, post "A successful Git branching model")
Jakub Narębski also mentions the config
merge.ff
:The fast-forward is the default because:
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:
The OP adds in the comments:
Jefromi answers:
More generally, I add:
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".
让我详细介绍一下 VonC 的 非常全面的答案:
首先,如果我没记错的话,Git 默认情况下不会在快进中创建合并提交 > 案例来自于考虑单分支“平等存储库”,其中相互拉取用于同步这两个存储库(您可以在大多数用户文档中找到第一个示例的工作流程,包括“Git 用户的手册”和“版本控制示例”)。在这种情况下,您不使用拉来合并完全实现的分支,而是使用它来跟上其他工作。当您碰巧进行同步保存并存储在存储库中以供将来使用时,您不希望有短暂且不重要的事实。
请注意,功能分支和在单个存储库中拥有多个分支的有用性只是后来才出现的,随着具有良好合并支持的 VCS 的更广泛使用,以及尝试各种基于合并的工作流程。这就是为什么 Mercurial 最初只支持每个存储库一个分支(加上用于跟踪远程分支的匿名提示),如“Mercurial:权威指南”的旧版本中所示。
其次,当遵循使用功能分支的最佳实践时,即功能分支应该全部从稳定版本(通常是从最后一个版本)开始,以便能够挑选和使用通过选择要合并的功能分支来选择要包含的功能,您通常不会处于快进情况...这使得这个问题毫无意义。在合并第一个分支时,您需要担心创建真正的合并而不是快进(假设您没有将单次提交更改直接放在“master”上);所有其他后来的合并当然都处于非快进情况。
华泰
Let me expand a bit on a VonC's very comprehensive answer:
First, if I remember it correctly, the fact that Git by default doesn't create merge commits in the fast-forward case has come from considering single-branch "equal repositories", where mutual pull is used to sync those two repositories (a workflow you can find as first example in most user's documentation, including "The Git User's Manual" and "Version Control by Example"). In this case you don't use pull to merge fully realized branch, you use it to keep up with other work. You don't want to have ephemeral and unimportant fact when you happen to do a sync saved and stored in repository, saved for the future.
Note that usefulness of feature branches and of having multiple branches in single repository came only later, with more widespread usage of VCS with good merging support, and with trying various merge-based workflows. That is why for example Mercurial originally supported only one branch per repository (plus anonymous tips for tracking remote branches), as seen in older revisions of "Mercurial: The Definitive Guide".
Second, when following best practices of using feature branches, namely that feature branches should all start from stable version (usually from last release), to be able to cherry-pick and select which features to include by selecting which feature branches to merge, you are usually not in fast-forward situation... which makes this issue moot. You need to worry about creating a true merge and not fast-forward when merging a very first branch (assuming that you don't put single-commit changes directly on 'master'); all other later merges are of course in non fast-forward situation.
HTH