rebase 还是 merge?

2021-09-18 11:01:05 +08:00
 wiirhan

大家在项目里合并代码是用 rebase 还是 merge ? 两个远程分支合并,用 merge 会产生一个无意义的提交,次数多了分支线就很乱。

11237 次点击
所在节点    git
81 条回复
zhw2590582
2021-09-18 17:34:10 +08:00
看过一篇老外教程说:永远不要在公共分支 rebase
oakland
2021-09-18 17:47:49 +08:00
@zhw2590582 此 rebase 非彼 rebase
xiubin
2021-09-18 18:01:59 +08:00
单人分支 rebase 公共分支;单人分支 merge into 公共分支
Kobayashi
2021-09-18 18:02:56 +08:00
@Kobayashi 仔细想了一想,之前的长回复应该补充一点。主要是楼主的问题应该从两个角度回答,我只回答了其中一部分。

楼主问题提到“2 个远程分支合并”,是指原来两个分支都和主分支在一条线上,如果一个分支先合并,另一个与更新后的主分支分叉,合并时发生了 merge --no-ff. 按照楼主的理解,分支合并应该是

1. rebase 到主分支,保证分之合并前没有分叉
2. merge --ff,保证分支合并后没有额外 merge commit.

其实这就是 非 Git 版本控制工具 的分支使用逻辑:分支历史必须是一条线,分支起点必须是主分支最新提交。如 SVN.

这个问题实际要分为 2 个部分:

1. 合并分支前是否要 rebase?
2. merge 是否使用 --ff 快速推进,要不要不产生额外的“合并提价”?

我之前的回复其实只针对了 2,介绍了 Git 分支非一条支线的特性,推荐了 --no-ff 合并。

如果只针对 1,可以根据情况:

- 如果向主分支合并时发生冲突,可以合并时解决冲突。或者 rebase 解决冲突,再合并。
- 或者你想让提交历史图( timeline )更清晰一点,也可以先做 rebase 一下。如当前分支和合并前主分支时间隔的太久,直接合并后分支线头尾跨得太远,不好查看。或者是不想多个分支线合并后有交叉。(敲完才发现楼上 @msg7086 回复,参考其“理想的 timeline”一图,非常漂亮)
- 或者分支合并前不做 rebase,降低工作流使用门槛。如 Github PR 合并方式:直接给你在网页上整一个按钮,点击后 merge --no-ff.

不管哪种情况,推荐 merge --no-ff 优先。一些特殊情况,如分支上 只有 1 个新提交,可以 --ff 快速推进。
ospider
2021-09-18 18:22:38 +08:00
都 2021 年了,竟然还有人在推荐 git flow
supereasy
2021-09-18 18:31:14 +08:00
从 16 年到现在 一直 merge --no-ff 不会转为 rebase
celeron533
2021-09-18 20:11:53 +08:00
我有时候先 interactive rebase,压掉不必要的 commit,最后 merge
charlie21
2021-09-18 20:26:24 +08:00
“次数多了分支线就很乱,怎么办”,如果关注的问题是这个,那么就你需要先列出你操作的分支名,然后会走向两种解决方式:
1 增加分支,**增加一个分支作为 ‘缓存分支’ **,即改变分支策略
2 分支不变,改变 merge 命令

如果是办法 1,那么解决办法会非常简单,你会把 ‘造成分支错乱’ 归因为提交错了分支线。

如果你需要前后三次提交(或无数次提交),将会导致分支错乱的原因是 你只有 2 个分支,自己的 branch -> main branch,这样 main branch 会很快被写入;将会导致分支清晰的原因是 你现在有 3 个分支,自己的 branch -> develop 分支 -> main branch 。这样因为多了一个分支,所以 develop 分支仍然会很乱( develop 分支是 ‘缓存分支’,等于为 main branch 作了缓存),故而 main branch 会保持清晰。

https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow 图示
https://www.atlassian.com/blog/git/written-unwritten-guide-pull-requests

如果是办法 2,那么,哈哈 ... 这根本不是 merge 命令的问题 ... 你需要重新归因,而不是拿出某个命令来就用。实际上它是 pull request 策略的问题,而不是 merge 策略的问题。它是人员责任划分的问题,不是 git 的问题:是责任划分来指导 pull request 策略和具体 git 操作,而不是相反。相反只有颠覆,而且是盲从般的颠覆
Kobayashi
2021-09-18 20:36:14 +08:00
@ospider git flow 是严格了点,实践中未必要严格遵守使用,但其中的分支使用思想经久不衰。鉴于楼主目前遵循的分支使用逻辑是分支合并结果要保留单一直线,我觉的推荐 git flow 正合适。
kaneg
2021-09-18 20:38:06 +08:00
我看到过很多人把 git 的 commit 当成草稿箱,提交很多无意义的改动,每次 commit 基本在修改错别字或者反复 rollback 。针对这种情况,在 PR merge 到 master 之前,最好 squash 。否则如果日后做 trouble shooting 的时候,其中的每条 commit 就是对别人的折磨。
xuanbg
2021-09-18 20:51:35 +08:00
项目比较复杂,多人同时维护。用 rebase 简直就是噩梦。
wukongkong
2021-09-18 21:08:36 +08:00
@Pipecraft 我们用这个导致了半年的 commit 丢失,负责人不会用,瞎用,,,,
uselessVisitor
2021-09-18 21:11:37 +08:00
永远 merge
namelosw
2021-09-18 21:53:18 +08:00
这其实本质和团队质量有关:

其实最理想的情况就是努力培养团队,素质都不错,需求拆分合理,自动化测试和持续集成也做得很好,所有人在同一个分支疯狂 rebase 效果是最好的。

如果有个总记不住拉代码,互相甩锅,功能拆分不完整,提代码就挂掉别人的功能,代码合进来也不知道对不对的团队,那只能先 merge…
devfeng
2021-09-19 03:20:40 +08:00
这个可以灵活应对吧,能用 rebase 的情况下尽量 rebase 了
IvanLi127
2021-09-19 13:04:49 +08:00
请求科代表做总结
24bit
2021-09-19 19:41:08 +08:00
开发分支 rebase,合并 master fast forward merge
Jsonz
2021-09-19 22:33:04 +08:00
@weiwenhao 我想了一下我们现在的流程
各个 feature 会从 master 拉取分支,比如 featureA 、featureB 、featureC
如果开发的过程中,master 上发现一个 bug,则会基于 master 拉取一个分支 hotfixA,改好合并到 master 自动发布
发布完触发各个 feature 分支会自动 merge master 。
假如这时候 featureA 测试完成,要发布的话,是 merge 到 master,发到线上发现有 bug,直接回滚上一个 merge 节点不就好了...
git reset HEAD^ --soft 然后再修改代码提交先回滚?

这样可以解决吗
ychost
2021-09-20 20:31:23 +08:00
rebase 容易翻车,操作不熟
SmiteChow
2021-09-22 10:30:51 +08:00
rebase 是私有操作=你写了半天远程有更新且跟你改动有冲突你很不情愿需要及时解决并以此为基础继续干
Merge 是公开操作=你写完了现在就是要合并推送到远程让其他人都瞧瞧你的改动有多么牛逼

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://tanronggui.xyz/t/802718

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX