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 · 5187 次点击
    这是一个创建于 1405 天前的主题,其中的信息可能已经有所发展或是发生改变。
    比如说 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   ·   实用小工具   ·   2739 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 12:10 · PVG 20:10 · LAX 04:10 · JFK 07:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.