V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
git
Pro Git
Atlassian Git Tutorial
Pro Git 简体中文翻译
GitX
abcbuzhiming
V2EX  ›  git

请教关于 git 的分支合并的最佳实践,多人协作时 hotfix 该如何处理?

  •  1
     
  •   abcbuzhiming · 218 天前 · 2017 次点击
    这是一个创建于 218 天前的主题,其中的信息可能已经有所发展或是发生改变。
    在看 git 合并策略的文章时注意到了一个案例,dev 分支上加入了一个 A 文件,然后合并给了 main 分支。dev 分支继续向前开发。此时 main 分支发现新加入的 A 文件有 bug,于是紧急 fix,撤掉了合并,并生成一个新的 commit 。。此时 dev 在向前推进了一个 commit,然后此时 dev 再次合并到 main,合并后发现 main 内部“丢失”了 A 文件。

    那篇文章解释这个现象是“三向合并”导致的,因为,因为 main 撤销合并时,实际对 A 文件做了删除,而 dev 分支直到第二次合并时对 A 没有任何改变,所以这个"对 A 改变"的行为在版本上说是最新的,于是合并后,A 就被删除了。

    这个问题让我产生的疑问是:
    *.按这个理解,最好不要在 main 分支上直接做任何改动?
    *.但是如果我要 hotfix 的时候,该怎么操作呢?难道 hotfix 的改动需要通知到 dev 去?也就是 hotfix 合并到 dev,那如果人多一点,同时有十几个个 dev 分支在开发,一个 hotfix 就要发十几次次合并?
    *.而且,像上面这文里提到的,hotfix 需要删除文件,把 hotfix 合并到 dev,肯定会导致 dev 的文件也被删掉,这是不是有点不妥?
    16 条回复    2021-04-26 20:24:26 +08:00
    yiXu
        1
    yiXu   218 天前   ❤️ 3
    1. 如果 main 需要删除 A 文件,应该从 main 分支分出 一个 delete-A 的分支,提交删除 A 文件的 commit,然后合并到 main 分支。
    2. 如果 dev 分支与 main 分支有冲突,应该先 merge main 分支到 dev 分支,然后解决冲突,再将不会与 main 分支冲突的功能完善的 dev 分支 merge 进入 main 分支。

    个人的操作是这样的。
    janxin
        2
    janxin   218 天前   ❤️ 1
    以 git-flow 实践为例,git-flow 提供一个特定的 “hotfix” 工作流程:

    https://www.git-tower.com/learn/git/ebook/cn/command-line/advanced-topics/git-flow/#hotfix
    janus77
        3
    janus77   218 天前
    main 分支不要改动
    你说的情况,正确办法应该是这样的:main 拉一个新分支做 hotfix,该分支删掉 A 文件。然后先合到 dev 分支上去,再从 dev 合到 main 。
    针对你的多个 dev 分支,这里应该有一个主 dev 分支的情况,各自开发的时候从主 dev 拉出子 dev 。子 dev 开发完成以后要合并到主 dev,此时需要先从主 dev 反合到子 dev,再从子 dev 合到主 dev,这是防止上面所说的冲突。另外主 dev 是长期存在的,子 dev 在本期开发完成以后就可以删掉了。
    zhengxiaowai
        4
    zhengxiaowai   218 天前
    既然都是 hotfix 肯定不会管你开发分支了,此时针对 master 再提交一个 commit 即可,没太理解撤掉合并是什么意思? revert 也是产生一个单独的 commit

    此时 master 分支比 dev 分支多了一个 commit,dev 分支只需要 rebase 一下 master 即可,如果不去 rebase 一下 dev 分支下次提 merge request 时候会冲突,修改冲突即可。
    abcbuzhiming
        5
    abcbuzhiming   218 天前
    @janus77
    正确办法应该是这样的:main 拉一个新分支做 hotfix,该分支删掉 A 文件。然后先合到 dev 分支上去,再从 dev 合到 main
    ======
    我的疑惑在这里,hotfix 删除 A 文件,再合并到 dev 分支上,这么干是否会导致 dev 分支的 A 文件被删掉?我觉得应该是会的,也就是说 dev 分支将不得不在合并后想办法去“找回”A 文件,这个体验似乎,有点糟糕?
    rosia
        6
    rosia   218 天前
    这头像。。。
    abcbuzhiming
        7
    abcbuzhiming   218 天前
    @zhengxiaowai 那篇文章显然是为了故意造成这个效果,才做这样的场景操作的,
    不过你提到的场景我也不太理解,为什么:
    master 分支比 dev 分支多了一个 commit,再和 main 分支 merge request 的时候就会报冲突?这个冲突的原因是什么?是因为 git 找不到合并需要的 base 节点了吗?
    brader
        8
    brader   218 天前
    我们可以从优秀的项目身上借鉴经验,让我们来看一个案例,前段时间( 4 月 15 日),以太坊柏林硬分叉,openethereum 节点进行 Berlin hotfix 的一个案例:

    - https://github.com/openethereum/openethereum/pull/366

    - https://github.com/openethereum/openethereum/commits/dev

    我们观看上面两个链接的 git 工作流,可以看到他的 hotfix 流程大致是这样的:

    - Merge branch 'berlin_hotfix' into release/v3.2.1
    - Merge branch 'release/v3.2.x' into main
    - Merge branch 'main' into dev

    从这里相信你能看出,当出现一个紧急严重的 bug 的时候,你首先应该做的是第一时间、最短时间解决线上的漏洞,抛开一切繁琐的影响你解决问题的因素(不要再去想其他分支的事情了,你已经没有时间了)。

    你首先应该从当前发布版本切出一个 hotfix 分支,修复后,第一时间将该修补提交合并到新的发布版本,这时候你已经完成了你最应该做的,最紧急的事情,接下来,你就可以按部就班的,逐步将该修复合并到其他分支。


    当然,我们现实项目中,可能少了像开源项目有发布版本这个 tag,我们的线上可能就是 master 分支,但是原理是一样的。
    brader
        9
    brader   218 天前
    这里我再补充一点,只有非常紧急的 BUG,才走上面的一个流程。
    正常修复普通不紧急的 BUG,个人建议最好还是走平时的正常流程(开分支->修复->测试->上线)。
    git 是鼓励你频繁创建分支以及删除分支的,因为你线上使用的总是 master 分支,所以你的其他分支是无需合并本次 bug 修复的,因为该分支在开发完,就会被你删除,而后的新东西,你总是从 master 切个新分支出来。

    或者你还有一个持久存在的 dev 分支,那么你的 dev 分支,应该总是不定时的从 master 分支获得修复反哺。
    xuanbg
        10
    xuanbg   218 天前
    hotfix 是对已发布的 branch/tag 的 commit 进行修复。所以,测试通过后应该 Merge 到所有基于该 commit 的 branch 。
    abcbuzhiming
        11
    abcbuzhiming   218 天前
    @brader 目前大家说的流程我已经非常清晰了,只是这还是没有解决我说的那个疑问

    我在 hotfix 为了修复暂时删除了 A 文件,我肯定需要把 Hotfix 合并到 dev 上去的,此时 dev 上的 A 文件是不是会被删掉?按照顶楼说的那个场景:会,因为 hotfix 对 A 文件做的修改,在版本线路上比 dev 新。那么这就会造成 dev 在合并进来 hotfix 后,不得不重新去找回 A 文件,这个流程总觉得有点别扭
    janus77
        12
    janus77   218 天前
    @abcbuzhiming #5 如果没有发生冲突,那么你说的体验问题是不存在的。git 系统不是人类,对他来说 add 和 delete 是同一个级别的操作,没有好与坏之分
    SureE
        13
    SureE   218 天前
    推荐一篇文章
    Martin Fowler 的 https://martinfowler.com/articles/branching-patterns.html
    讨论了多种不同的分支管理模型,以及各自的优劣。
    brader
        14
    brader   218 天前
    @abcbuzhiming 会删除 A 文件的,这是完全没有问题的,因为你自己说了,你解决 hotfix 的办法就是删除了 A 文件。那么 A 文件的存在就是一个 BUG,所以你希望的 dev 分支也解决掉这个 BUG,那你就是要删除了 A 文件,如果说,不删除 A 文件也能解决 BUG,那么就说明你前面为了解决 BUG 而删除 A 文件的行为不是最优解。
    ThanksSirAlex
        15
    ThanksSirAlex   218 天前
    现在很多主流的 git flow 都不用 develop 分支了,只有 main 和需求分支,github flow 和 gitlab flow,都没有 develop 这个概念了,实际中 develop 分支的意义确实也不大
    yiXu
        16
    yiXu   218 天前   ❤️ 1
    @abcbuzhiming 个人实际测试了一下。

    1. 如果你的 A 文件在 dev 分支中没有任何修改。而 main 分支的热修复删除了 A 文件,当 dev 分支 merge main 分支则会删除 A 文件。

    2. 如果你的 B 文件在 dev 分支中有修改。而 main 分支的热修复删除了 B 文件,当 dev 分支 merge main 分支则会发生自动合并失败,而 B 文件则会显示冲突,需要自行在文件中解决冲突。并重新提交这个 commit,完成 merge 。
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3599 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 01:31 · PVG 09:31 · LAX 17:31 · JFK 20:31
    ♥ Do have faith in what you're doing.