git 两个分支合并的时候,如何保证代码运行正常? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
git
Pro Git
Atlassian Git Tutorial
Pro Git 简体中文翻译
GitX
sugarkeek
V2EX    git

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

  •  2
     
  •   sugarkeek 2021-02-23 11:12:42 +08:00 5634 次点击
    这是一个创建于 1694 天前的主题,其中的信息可能已经有所发展或是发生改变。
    比如说 M 和 B 分支,B 基于 M 新建里一个分支,M 和 B 各自开发着不同的模块。有几个问题:

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

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

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

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

    顺便再吐槽一下 Jetbrains 家之前的 git 的本地包 rebase 的翻译(现在忘记怎么翻译的了,衍入还是合并好像,反正容易搞混),一时和 merge 搞混,点了之后才发现是 rebase,悔恨交加,后面换回英文版了。不过在其他非主力的软件如 webstorm 本地包还没卸载,更新了最新版之后看了看 rebase 单词换回英文来。所以说一个信达雅的翻译确实很难啊。
    39 条回复    2021-02-24 16:35:20 +08:00
    wednesdayco
        1
    wednesdayco  
       2021-02-23 11:16:41 +08:00
    谁合并,谁解决冲突吧……看看 git flow 规范?
    baiyi
        2
    baiyi  
       2021-02-23 11:18:15 +08:00
    git 解决的就是代码冲突,你需要的是持续集成。
    imdong
        3
    imdong  
       2021-02-23 11:21:39 +08:00
    测试跟上,感觉写测试比写代码还难,工作量也很大.

    但是可以有效减少楼主的问题.
    yanqiyu
        4
    yanqiyu  
       2021-02-23 11:26:18 +08:00 via Android   1
    git 只是在文本层面处理代码,它管不到代码里面的逻辑,你需要的是测试用例
    teddy2725
        5
    teddy2725  
       2021-02-23 11:27:23 +08:00   2
    测试覆盖够了就没事,单元测试,功能测试,集成测试。
    no1xsyzy
        6
    no1xsyzy  
       2021-02-23 11:38:34 +08:00
    测试
    有时会注意到持续集成,主要是测试通常是集成的一环

    还有一方面,就是(尽量)不要两个人同时动一片逻辑。
    最糟糕的就是一个人为某个方法添加了新的特性,另一个人重构了这个方法…… 那几乎必有一个人打回重做。
    开源的自组织结构来说,多半会先提 issue 来宣告自己在动这块。

    这个翻译确实有问题,git rebase 应当作为术语不翻译。
    “变基” 这个翻译也不够牢靠,而且作为中文也很怪异。
    不过这中英文混杂…… 大刘直呼内行。
    TuringGunner
        7
    TuringGunner  
       2021-02-23 11:42:08 +08:00
    后合并的负责 rebase 解决冲突,然后把测试再跑一遍
    Chenamy2017
        8
    Chenamy2017  
       2021-02-23 11:46:27 +08:00
    这和 git 没有关系,动了代码就要测试,不管是人工修改的还是 git 自动解决冲突的。
    msg7086
        9
    msg7086  
       2021-02-23 11:47:36 +08:00
    当然靠集成测试了。两个分支合并产生冲突的话,不管是取其中一个分支的代码,还是把两个分支的修改合并在一起,都有可能导致代码出问题。

    简单说就是后合并的分支需要重做。
    soulmt
        10
    soulmt  
       2021-02-23 11:50:39 +08:00
    git 只负责冲突,不负责代码能不能跑起来,所以合并只是发布的第一步,应该有测试回归测试这一环节。
    crclz
        11
    crclz  
       2021-02-23 12:03:03 +08:00
    新建一个临时分支用于:1. 合并冲突 2. 运行单元测试、各种测试
    测试通过后,将该分支并入 master 分支。如果需要部署,就将 master 分支并入 release 分支。
    fucUup
        12
    fucUup  
       2021-02-23 12:15:45 +08:00
    我们的开源项目, 全球有 2 万个 git 账户在全球 7*24 协作, 没有你的糟心事, 都是水平问题, 合并的地方该是 true 还是 false, 你心里没有一点 B*****
    BeautifulSoap
        13
    BeautifulSoap  
       2021-02-23 12:22:53 +08:00
    公司的一个项目,提 pr 会用 github actions 自动进行单元测试,不通过直接打回,同时还会对提交的代码进行 linter 检查,不合规范也是打回,并且要求提交的 pr 细粒度必须小。但问题是,pr 小细粒度和单元测试必须通过经常是冲突的,感觉一个功能完成并合并需要的时间成倍增长

    不过有得必有失,作为项目来说这么做的确是有好处的
    fucUup
        14
    fucUup  
       2021-02-23 12:30:46 +08:00
    @BeautifulSoap en???? 意思就是说小颗粒度会 break 代码??? 这不合理. 是人的问题.
    sugarkeek
        15
    sugarkeek  
    OP
       2021-02-23 12:58:36 +08:00
    @wednesdayco
    @TuringGunner
    @msg7086
    好,会尝试运用这种思想在项目实践里,我去学习学习 git flow

    @imdong
    @teddy2725
    @Chenamy2017
    @soulmt
    测试确实很重要啊,也在想办法提高测试的效率

    @baiyi 也是在追求这种工作流

    @yanqiyu 嗯嗯,看来也只能在测试上下功夫

    @no1xsyzy 谢谢朋友的耐心指教,在测试上多下功夫。

    @crclz 谢谢朋友这种新思路

    @fucUup 相信 git 的潜力,我确实水平还有提升的空间,都是现学现用。

    @BeautifulSoap 感谢分享 git 在公司中的实践,我也是想 git 帮助项目更好的进行。
    jxlwqq
        16
    jxlwqq  
       2021-02-23 13:17:02 +08:00
    git 分支合并的原则是:“从哪来,回哪去”。
    代码是否正常运行的问题,就需要单元测试覆盖了。只要单元测试+code review 没问题,就可以合并。至于功能性的测试或者其他外部测试,就需要作为测试角色的人来做了。
    lizytalk
        17
    lizytalk  
       2021-02-23 13:20:43 +08:00
    单元测试
    yogogo
        18
    yogogo  
       2021-02-23 13:20:44 +08:00
    M 和 B 的虽然在开发不同的模块,但是可能会动到同一模块的地方,比如说配置,那么合并的时候不仅是说合并不同的模块,还得解决同一模块冲突的地方。
    ------------------------------------------
    这样分支是不是太混乱了,要是每个开发人员一个分支,那合并不得要出大事。不是应该要按开发版本做分支吗?
    hantsy
        19
    hantsy  
       2021-02-23 13:23:37 +08:00   1
    任何合并到 Master 直接跑 CI 测试就完了。
    hackape
        20
    hackape  
       2021-02-23 13:38:17 +08:00   2
    这事儿的本质跟 git 没有任何关系。

    即便是不分叉、线性地去开发,想象一下张三开发 A 模块,改了通用服务 C,提交完了,然后李四接着开发 B 模块,然后也改了服务 C 。你看这里面没有分叉再合并、产生冲突的过程,但也不能保证李四改完了的 C 就完全不出问题,除非李四充分理解自己的改动,这包括他需要去看张三的那部分代码。

    合并出现冲突,本质上面对的问题还是两个人分别改了同个东西如何保证不出错,要么是李四解决冲突的时候好好读代码,要么把张三叫过来,大家一起 review 一下。

    再退一步讲,哪怕只有张三一个人写东西,照样不能保证不出错,相信大家都有过看不懂自己的老代码的经验。

    所以说这事儿跟 git 没有半毛钱关系,而你说的问题,别的楼层提到的 CI/CD, TDD 都是有效的方法(如果不流于形式、好好执行的话),然而还是那句话 there's no silver bullet,这个话题没有最终答案的。
    learningman
        21
    learningman  
       2021-02-23 13:43:16 +08:00 via Android
    配置也不应该放在 git 里吧
    sillydaddy
        22
    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
        23
    across  
       2021-02-23 13:50:12 +08:00
    这显然是代码结构问题。模块调用 API 功能不停变,哪个团队受得了。
    BeautifulSoap
        24
    BeautifulSoap  
       2021-02-23 14:16:44 +08:00 via Android
    @fucUup ????这都想不明白???一个 api 修正,其中模型,repository,service,api,swagger 的变更必须拆分成不同的 pr 。你模型,repository,service 这些地方的结构或业务逻辑变了,上面的 api 逻辑没变,单元测试不是有非常大几率失败?这不就是细粒度分太细导致的单元测试失败?
    还有 swagger 是根据 api 请求的结构体自动生成的,api 请求的结构体是在 api 辩证的 pr 中被修改。那么请问自动生成的 swagger 文件 diff,是应该和请求结构体的变更一起提交呢,还是单独提交呢?
    细粒度分太细是真的经常出一些问题
    sugarkeek
        25
    sugarkeek  
    OP
       2021-02-23 14:26:24 +08:00
    @yogogo 你这么一说,我想了想,好像看到的项目都是一个开发版本一个分支点。

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


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


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

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

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

    也就是每一个模块都要保留几个周期的逻辑同时存在, 因为你要考虑你的上下游会回滚, 不这样做的话你就等着上新闻, 像微博公司经常 down 机上热搜
    msg7086
        27
    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
        28
    msg7086  
       2021-02-23 15:16:01 +08:00
    @sillydaddy
    我又特地看了一下,微软的这篇文章其实也不对,最合理的做法是 rebase 而不是 cherry-pick 或者 merge 。
    remarrexxar
        29
    remarrexxar  
       2021-02-23 17:01:42 +08:00
    自动化测试跟得上的话,所有要进 master 分支或者其他重要分支的代码都要跑 smoke testing 保证至少不影响主流程,如果功能本身影响主流程测试脚本要同步修改。此外还需要定时跑完整的 regression test 来发现其他可能出现的问题。
    AlynxZhou
        30
    AlynxZhou  
       2021-02-23 17:11:57 +08:00
    diff 本来的含义就是从一个状态到另一个状态有哪些变化嘛,至于这个变化是啥含义它不理解也理解不了,这是工具使用者的任务,不是工具自己的
    BeautifulSoap
        31
    BeautifulSoap  
       2021-02-23 17:22:22 +08:00 via Android
    @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
        32
    sillydaddy  
       2021-02-23 17:28:16 +08:00
    @msg7086 #28,那篇文章我看过但现在已经忘了。rebase 内部就是使用的 cherry-pick 啊。
    nocrush
        33
    nocrush  
       2021-02-23 17:32:51 +08:00
    合并前先 rebase 下目标分支,解决完冲突再 merge
    msg7086
        34
    msg7086  
       2021-02-23 18:03:18 +08:00 via Android
    @sillydaddy 方向反了。
    应该是让分支 rebase 到主干,你说的那是把主干 pick 到分支。所以我才说不管是 pick (或者你说的那种反向 rebase )还是 merge 都是不合适的。

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

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

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

    rebase 翻译看到过的最无语的是 变基。。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5802 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 01:45 PVG 09:45 LAX 18:45 JFK 21:45
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86