git 两个分支合并的时候,如何保证代码运行正常?

2021-02-23 11:12:42 +08:00
 sugarkeek
比如说 M 和 B 分支,B 基于 M 新建里一个分支,M 和 B 各自开发着不同的模块。有几个问题:

1. M 和 B 的虽然在开发不同的模块,但是可能会动到同一模块的地方,比如说配置,那么合并的时候不仅是说合并不同的模块,还得解决同一模块冲突的地方。

2. git 是有冲突对比的,包括用的 GUI 软件都有非常直观的冲突对比,通过几次合并发现了一些问题,git 是能解决文本冲突的对比,但是到了代码运行时,有时也会出错,即使我们觉得某个地方冲突了,采用哪方的代码才是正确的。

但是程序不能说有时出错啊,所以代码在开发的过程中,心中总是有种隐隐的担心合并的代码会出现问题。git 很强大,帮助我们管理大量的代码,但是就好像海下的冰山一样,很多东西我们都无法预料的到。

3. 总结一下就是,git 能解决代码不同,但是不能保证合并的代码正常运行。

顺便再吐槽一下 Jetbrains 家之前的 git 的本地包 rebase 的翻译(现在忘记怎么翻译的了,衍入还是合并好像,反正容易搞混),一时和 merge 搞混,点了之后才发现是 rebase,悔恨交加,后面换回英文版了。不过在其他非主力的软件如 webstorm 本地包还没卸载,更新了最新版之后看了看 rebase 单词换回英文来。所以说一个信达雅的翻译确实很难啊。
5155 次点击
所在节点    git
39 条回复
learningman
2021-02-23 13:43:16 +08:00
配置也不应该放在 git 里吧
sillydaddy
2021-02-23 13:46:16 +08:00
LZ 提的还是比较明显的合并冲突。肉眼毕竟还可以检查。

更厉害的是,有时合并会**无声无息**地埋下隐藏的炸弹。比如使用 cherry-pick

比如微软的技术文章很详细描述了,“Stop cherry-picking, start merging” (不要使用 cherry-pick,开始使用 merge 吧!)
https://devblogs.microsoft.com/oldnewthing/20180312-00/?p=98215

但即使如此,cherry-pick 该用还是用吧,毕竟中招几率很小啊,加上测试就更小啦。
across
2021-02-23 13:50:12 +08:00
这显然是代码结构问题。模块调用 API 功能不停变,哪个团队受得了。
BeautifulSoap
2021-02-23 14:16:44 +08:00
@fucUup ????这都想不明白???一个 api 修正,其中模型,repository,service,api,swagger 的变更必须拆分成不同的 pr 。你模型,repository,service 这些地方的结构或业务逻辑变了,上面的 api 逻辑没变,单元测试不是有非常大几率失败?这不就是细粒度分太细导致的单元测试失败?
还有 swagger 是根据 api 请求的结构体自动生成的,api 请求的结构体是在 api 辩证的 pr 中被修改。那么请问自动生成的 swagger 文件 diff,是应该和请求结构体的变更一起提交呢,还是单独提交呢?
细粒度分太细是真的经常出一些问题
sugarkeek
2021-02-23 14:26:24 +08:00
@yogogo 你这么一说,我想了想,好像看到的项目都是一个开发版本一个分支点。

我现在呢,git 在项目里的实践是看到一些 git 介绍的,说是方便团队协作,每个人一个分支,开发不同模块,最后合并到主线,项目就干好了。基于这个思想,我才采用一个人一个分支的。


@hackape 嗯嗯,there's no silver bullet.


@learningman 我是举个例子,就是有可能有交集的地方。有些早期小项目图快,会公用,后面的话我都会注意这个问题。

@sillydaddy 学习了,感觉把主题都升华了。
fucUup
2021-02-23 14:28:54 +08:00
@BeautifulSoap

我们有 40 个微服务, 全球团队 500 人一起开发, 每一次变更都是前后兼容, 不存在你说的问题, 任何 break 代码的提交都会被拒绝, 不应该先重构了一个模块, 再去补写另外一个模块, 这是常识

也就是每一个模块都要保留几个周期的逻辑同时存在, 因为你要考虑你的上下游会回滚, 不这样做的话你就等着上新闻, 像微博公司经常 down 机上热搜
msg7086
2021-02-23 15:12:13 +08:00
@yogogo @sugarkeek
这两个东西原本也不是冲突对立的。
版本需要开分支,是因为会有稳定版和开发版之分。
功能和模块开分支,是因为要多人同时进行开发。
比如你们 1.5 版本发布后,开始开发 1.6 。那么可以先分出 dev-1.6 分支,然后在 1.6 分支上再按照 feature 分出不同的分支。开发完以后先 MR 到 dev-1.6 上,然后等全部测试完了,再 merge 到 master 上,发布上线。

@sillydaddy cherry-picking 和 merging 本质上是差不多的,这和无声无息也没关系,不管有声还是无声,最终都只有测试才能决定合并是否安全。cherry-picking 无错并不代表合并成功。同时这也不应该成为不用 cherry-pick 的理由。
msg7086
2021-02-23 15:16:01 +08:00
@sillydaddy
我又特地看了一下,微软的这篇文章其实也不对,最合理的做法是 rebase 而不是 cherry-pick 或者 merge 。
remarrexxar
2021-02-23 17:01:42 +08:00
自动化测试跟得上的话,所有要进 master 分支或者其他重要分支的代码都要跑 smoke testing 保证至少不影响主流程,如果功能本身影响主流程测试脚本要同步修改。此外还需要定时跑完整的 regression test 来发现其他可能出现的问题。
AlynxZhou
2021-02-23 17:11:57 +08:00
diff 本来的含义就是从一个状态到另一个状态有哪些变化嘛,至于这个变化是啥含义它不理解也理解不了,这是工具使用者的任务,不是工具自己的
BeautifulSoap
2021-02-23 17:22:22 +08:00
@fucUup 老哥建议你再仔细看看我想说的内容,我和你要讲的东西根本不是一回事,你讲的是整体的管理,我讲的是具体到每个服务内代码的修改怎么提 pr

打比方具体来说项目要求给某 api 增加个字段,一般建个 feature/add_field 分支改好代码就行了,但是因为项目要求彻底细分 pr,所以会要求将这一个变更内容拆分成 feature/add_field_change_model,feature/add_field_change_repository,feature/add_field_change_service 等等分支,review 完成之后合并入 feature/add_field 分支,等全部代码都确认没问题后再合并到 master 或者其他环境分支


那么我请问你,feature/add_field_change_model 我改了模型但是上层没有改导致 api 单元测试失败了,我该怎么办?顺便一提因为这些细分的分支只是合并入 feature 分支,所以不会影响环境里跑的服务
sillydaddy
2021-02-23 17:28:16 +08:00
@msg7086 #28,那篇文章我看过但现在已经忘了。rebase 内部就是使用的 cherry-pick 啊。
nocrush
2021-02-23 17:32:51 +08:00
合并前先 rebase 下目标分支,解决完冲突再 merge
msg7086
2021-02-23 18:03:18 +08:00
@sillydaddy 方向反了。
应该是让分支 rebase 到主干,你说的那是把主干 pick 到分支。所以我才说不管是 pick (或者你说的那种反向 rebase )还是 merge 都是不合适的。

rebase 不是基于 cherry pick 。这两个命令本来就都是 commit 的语法糖,没有内部不内部之分。
est
2021-02-23 18:06:49 +08:00
LZ 想要的东西是,两个人同时改一个东西,然后有一个神奇的自动系统或者机制,能让这两人改出来的东西不会有冲突和毛病。。。
chiu
2021-02-23 23:23:05 +08:00
>> git 能解决代码不同,但是不能保证合并的代码正常运行
这个主要还是看你们组使用 git 开发遵循的 workflow 。如果合并后代码运行出错,那基本是人为的问题,毕竟 resolve conflict 的时候,是人为决定怎么 resolve 的。如果 feature 分支出来自成一支后开发了很多东西,那 rebase 回 master/main 的时候大量 conflicts 在所难免。
honjow
2021-02-24 00:01:36 +08:00
git 不负责这东西,测试负责
1OF7G
2021-02-24 00:39:36 +08:00
Merge 没有冲突,不代表合并后的代码正确地表达了你的意图,甚至不代表这些代码能够正常执行。

Git 只是帮你追踪代码变动,你自己必须清楚每次 commit 引入了哪些些变动。通常在自己编辑完代码后立即进行 commit , 对引入的变动非常清楚。而 Merge 也是一次引入变动的 commit,但陷阱就是,你可能并不清楚这次 Merge commit 所引入的代码变动。(可能是你很久之前写的 /或者是别人写的)。

从源头上解决问题的方法不是使用各种测试,而是 review 这次 Merge 所引入的变动。本质就是,把 Merge 盲目引入的变动,变成你思考后所认同的变动。下一步,才是各种测试。
eastphoton
2021-02-24 16:35:20 +08:00
git 管合并,不管运行。。。

rebase 翻译看到过的最无语的是 变基。。

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

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

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

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

© 2021 V2EX