关于 git 工作流我有个小疑问(冲突在本地还是远端解决)

2022-03-27 13:56:22 +08:00
 unco020511

正常开发中,我们会从 main->new branch feature 分支,当我的 feature 开发完毕后,origin/main 可能已经更新了很多个 commit(从其他 feature 合并而来),很可能存在冲突,此时我有两种操作方式,哪种方式更好?

  1. 先在本地将 main pull 之后,将 local/main 合并到 local/feature,在本地解决冲突,然后 push origin feature,然后在 gitlab(或 github)提交 merge request(或者 pull request),将 origin/feature 合并到 origin/main
  2. 直接 push origin feature,然后在远程提交 merge request(或者 pull request),在远程仓库(可视化工具)解决冲突,然后将 origin/feature 合并到 origin/main

这两种方式各有什么优缺点?哪种更适合企业项目的团队合作?

5433 次点击
所在节点    程序员
42 条回复
imkerberos
2022-03-27 13:58:08 +08:00
远端不用重新 approve .
unco020511
2022-03-27 14:02:45 +08:00
@imkerberos approve 肯定都需要,我们是两个同事 review 后 approve,才能进行 mr
momocraft
2022-03-27 14:03:09 +08:00
1 才有机会解决冲突后运行和测试

除非你们有足够好的自动测试 不需要手工保证
unco020511
2022-03-27 14:07:10 +08:00
@momocraft 你的意思是 1 可以在 mr 之前基于 feature 进行测试是吗?我这里简化了,实际上肯定不是直接 mr 到 main 上,一般会有个 dev,2 的话也可以 mr 之后基于 dev 测试
imkerberos
2022-03-27 14:09:12 +08:00
我的意思是 重新 approve.
unco020511
2022-03-27 14:10:33 +08:00
@imkerberos 推荐 1 是吧
EastLord
2022-03-27 14:37:20 +08:00
1
lidlesseye11
2022-03-27 14:37:40 +08:00
1
cowcomic
2022-03-27 14:53:12 +08:00
1 提交代码要保证合并的正确性和正常运行
janus77
2022-03-27 14:59:19 +08:00
对于比较大的团队和比较严格的规范,应该是远程合并,因为普通开发不应该有 write main 分支的权限。
而对于简单项目和小团队,以及实际操作上来讲,本地合并的话,解决冲突更容易,因为远程合并一般都是命令行或者 web 界面,本地可以用一些 gui ,鼠标点点就能正确合并,操作更简单。
sue0917
2022-03-27 15:00:42 +08:00
楼上在说啥😂
Macolor21
2022-03-27 15:10:32 +08:00
@janus77 #10

让 feat 分支 rebase main ,然后解决冲突后 push feat 再 开启 mr 就可以了,不用 merge 到 main 再 push main 。
GeruzoniAnsasu
2022-03-27 15:20:21 +08:00
其实没有「远端解决冲突」一说,所有的合并和冲突解决都是在叶子节点上或者说都在 git 的「客户端」进行的。

web 界面只是自动做了一些额外的事情而已,跟你在本地用一个 GUI git 工具是一回事。




> 当我的 feature 开发完毕后,origin/main 可能已经更新了很多个 commit(从其他 feature 合并而来),很可能存在冲突

此时你 **不应该进行任何 MERGE 尝试**。

1. 首先应该在本地切换到主分支( dev/main/master ),拉取远程的状态。由于你不可能直接在这些分支上修改,所以这一步不会产生任何冲突,仅仅是快进
2. 切回到你的开发分支,把它 rebase 到主分支上,此时产生冲突,resolve ,重新 commit 。
3. 由于到目前为止你还是只修改过你的独占分支(就算有远程也是可以随便 push -f 的那个),所以不会对其他人产生任何影响。
4. push 你 rebase 过后的分支,开启或刷新 MR





之所以采用不断 rebase 分岔点的方式是因为,如果你不进行 rebase ,merge 操作时是一个三路合并,而三路合并是一个**既复杂又存在危险性** 的操作


(!!) 其实我本来想简单解释一下为什么三路合并会出问题,但在我搜索看了近一个小时文章后,我选择放弃解释:
https://www.waynerv.com/posts/git-merge-intro/
https://git-repo.info/zh_cn/2020/03/something-about-git-merge/
https://actake.github.io/2021/03/21/git%E5%BF%85%E7%9F%A5%E5%BF%85%E4%BC%9A-%E5%88%86%E6%94%AF%E5%90%88%E5%B9%B6%E9%82%A3%E4%BA%9B%E4%BA%8B/





(!!) 因为这已经是我至少第 4 次搜索这个问题然后仍然没有完全搞懂了


如果采用 rebase - merge FF 的方式,合并操作等同于在对方分支上把你做过的操作重放一次,心智负担和风险要小得多。只有一个麻烦,因为是重放,当你的 commit 序列一开始就与对方冲突时,这个冲突会有传递性(对方是 A ,你第一个提交把 A 改成了 B ,后面的提交全部在用 B ;发现冲突后你决定改成 C ,那么当你 rebase 重放的时候所有后面的提交都会不断发生 B 和 C 的冲突)。但这都可以通过减少 commit 修改量和 squash 改善,相比起三路合并能由(虽然存在疏忽的)正常操作产生 **无感知的** 丢修改相比,成本显然要低得多
rickll
2022-03-27 15:24:13 +08:00
如果在本地已经有冲突的代码,为什么还要提交到远端去? 别人把这个冲突代码拉下来不是骂娘。 所有冲突都应该在本地解决。
maninfog
2022-03-27 15:27:20 +08:00
一般这种情况是 1.git fetch 2.git rebase origin/master 3. git push -f (rebase 之后 feature 分叉了所以需要 force push)
rbe
2022-03-27 15:30:06 +08:00
这两个方式没有什么本质区别呀,核心都是自己 feature 分支随便玩,自己单独开发的话 rebase 都可以,保证合入不冲突,最后 mr 到 main 都只有一个 commit 。
区别就是你在本地 editor 解决冲突还是网页端可视化工具解决冲突。大概率复杂情况下你都需要在本地解决的,网页端都不好搜索代码
Chism
2022-03-27 15:40:20 +08:00
我倾向于本地解决冲突,还能顺便测试一下是否运行正常
cyang812
2022-03-27 16:53:24 +08:00
@GeruzoniAnsasu rebase 到 main 和 merge main 有什么区别呢?
ClericPy
2022-03-27 16:54:58 +08:00
不太复杂的小项目 git flow 感觉有点复杂, Github flow 就够用了

rebase 吧, 你的基被人往前推了, 那就变基到跟线上一致提个 PR, 主线分支光溜溜一根挺好的.
jessun1990
2022-03-27 17:01:37 +08:00
git rebase ,本地解决冲突,再 push 上去。

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

https://www.v2ex.com/t/843165

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

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

© 2021 V2EX