V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
rockyliang
V2EX  ›  程序员

关于 git 协作的一个问题

  •  
  •   rockyliang · 2022-05-15 01:11:16 +08:00 · 2981 次点击
    这是一个创建于 923 天前的主题,其中的信息可能已经有所发展或是发生改变。

    场景: 在某个项目中,小明和小红开发两个不同的功能,于是他们基于项目的 master 分支分别创建了自己的 feature 分支,小明的是 feature A 分支,小红的是 feature B 分支。

    在各自的开发过程中,小明编写了一些共用函数,小红发现自己也需要用到这些函数,于是想把这些函数同步到自己的 feature B 分支中来,这个时候可以怎么做呢?

    首先肯定不能把小明的整个 feature A 分支合并过来,因为小红需要的只是那些共用函数。

    目前我想到的只能是,通过复制粘贴把需要的代码同步过来。

    不知各位大神平时在开发中有没有遇到过这种场景,有的话你们是怎么解决的呢?

    23 条回复    2022-05-16 18:34:44 +08:00
    billlee
        1
    billlee  
       2022-05-15 01:25:37 +08:00
    cherry-pick 和 rebase
    duke807
        2
    duke807  
       2022-05-15 01:35:51 +08:00 via Android   ❤️ 2
    小明做的不對,他應該把共用的修改提交到 master 分支,然後再合併到 A 分支使用,這樣 B 也就可以 merge master 分支了

    小明開發調試的時候可以在 A 分支直接改,但是提交到服務器之前,要把共用部分整理到 master 分支

    以上是 A 和 B 分支都長期依附 master 分支的情況
    EastLord
        3
    EastLord  
       2022-05-15 01:37:40 +08:00 via iPhone   ❤️ 2
    开发 feature A 的时候把公共函数作为一次提交,剩下的代码作为其他提交,提 pr 的时候可以压缩提交; feature B 可以把 feature A 公共函数的提交 cherry-pick 过来。
    InDom
        4
    InDom  
       2022-05-15 01:55:35 +08:00   ❤️ 1
    建立分支 C, 将两个人共同的代码部分写入 feature/common-c

    A B 分支各自将 C 分支合并进来,

    我现在对于分支的思想是: 搭积木, 将一个功能尽可能拆散,哪怕任意一个独立的分支都是无法执行的, 但他们通过某种组合在一起是可以执行的.

    所以, 产物是一系列分支的组合, 而不是分支即结果.
    FrankHB
        5
    FrankHB  
       2022-05-15 02:19:26 +08:00
    这看来是详细设计评审没做到位,或者根本就没怎么做。如果小明和小红清楚地知道对方在干啥,这种共用函数一般不会是实现了一半才发现,要么就是发现了也少到能容忍复制粘贴实现的程度。(还有种情况:A 和 B 大到设计时没法一次性做到那么细,直接扔给单人负责却又不及时同步以至于根本没法及时注意到别人做了啥,但那样是项目计划就离谱了。)
    正常做法是知道共用函数后开 upstream feature branch 或者并行开 common feature branch (极端情况下嫌弃 feature 少 branch 多也可以扔 master 里,如果项目规则允许)优先实现,然后直接基于这个 branch 或者包含这个 branch 修订的某个 tag 开 A 和 B branch 。
    但既然开发了一半,如果不像停工重建这个流程的话,就 cherry-pick+rebase 补救吧。是不是 squash 看约定,改动太大可能会很麻烦。
    msg7086
        6
    msg7086  
       2022-05-15 04:52:58 +08:00 via Android   ❤️ 2
    新开一个 feature branch ,把共用功能交进去合并,然后其他分支去 rebase 。
    liuzhaowei55
        7
    liuzhaowei55  
       2022-05-15 08:27:09 +08:00 via iPhone
    赞同 6 楼的做法,不过我一般是选择 merge 。
    aheadlead
        8
    aheadlead  
       2022-05-15 08:43:33 +08:00
    楼上说的都对… 但实际情况是公共部分直接往 master 里送
    (怎么快怎么来一把梭)
    alanhe421
        9
    alanhe421  
       2022-05-15 09:46:15 +08:00 via iPhone
    个人认为实际情况下是 cherry pick ,当然本质是又一次 commit ,将来 mr 也可能会是冲突分一部分,需要人工选择下。

    当然如上所说分支法,包法都没毛病,只是小需求下会是如上做法。
    jaredyam
        10
    jaredyam  
       2022-05-15 10:05:00 +08:00   ❤️ 1
    上面说的 merge + rebase 和 cherry-pick + rebase 实际效果不都一样嘛,单拎出来这个公用函数的 commit 先放到两个开发分支的底层再 rebase 其它 changes (如果不能直接把这个 commit 放到 master 的话)。
    renmu123
        11
    renmu123  
       2022-05-15 10:17:20 +08:00 via Android
    现实的情况:复制黏贴
    janus77
        12
    janus77  
       2022-05-15 10:33:30 +08:00
    为什么不能直接 merge 。A 和 B 都是基于 master 的,A 和 B 最终也要合入 master 。那我 B 想合 A 和想合 master 有什么本质区别吗
    当然只是嘴上说说而已。正常的做法是,公用部分不能让 A 单独开发,应该拉个 C 分支先开发完了合到 master ,然后 A 和 B 自己去合 master 。也可以把公用部分写到一个单独文件或者目录里,只提交这个文件,然后合进 master ,然后 B 在去合 master 。
    aleen42
        13
    aleen42  
       2022-05-15 11:08:50 +08:00 via Android
    如果不希望推上 remote ,可以考慮把有需要的提交打 patch
    rockyliang
        14
    rockyliang  
    OP
       2022-05-15 12:34:24 +08:00   ❤️ 2
    @janus77 不能把 B 合进来,主要是考虑到 A 和 B 是两个不同的功能,上线时间不一样。如果 A 功能先上线,之前你又把 B 分支的代码合进来了,那 A 上线的时候,岂不是把 B 功能的代码也发布到线上去了吗?

    然后针对你说的正常做法,我们这里是,只有测试通过、准备上线的功能代码,才会合到 master 。所以公用部分可以拉个 C 分支开发,但不能把 C 分支合到 master 。最后 A 和 B 自己去合分支 C
    janus77
        15
    janus77  
       2022-05-15 14:06:36 +08:00   ❤️ 1
    @rockyliang #14 如果 A 和 B 是两个独立发版的功能,那我觉得这块公用代码本来就不应该那样理解,只是你们都需要用到而已,但是不能复用。又想要两者分开发布,又想同时复用同一套代码,没有这种事,除非是用依赖库的形式。而这也就是我说的那种开 c 分支 /开单独目录,那个目录你们可以视为一个依赖库。只是他随 master 分支变动而已。当然你也可以做成产物依赖而非源代码依赖。这样就不存在 git 的问题了
    Macv1994
        16
    Macv1994  
       2022-05-15 14:08:38 +08:00
    patch 或者 cherry-pick 吧
    Helsing
        17
    Helsing  
       2022-05-15 14:14:01 +08:00 via iPhone
    @rockyliang #14 你这种情况打 patch 或 cherry- pick 最合适
    xuanbg
        18
    xuanbg  
       2022-05-15 14:33:52 +08:00   ❤️ 1
    要规范就开 C 分支,要简单直接 main/master 分支上面写。
    unco020511
        19
    unco020511  
       2022-05-16 09:18:29 +08:00
    这不正是 cherry-pick 的场景吗,feature A 的公共部分作为一个 commit push,然后就在 B 中 pick 过来
    unco020511
        20
    unco020511  
       2022-05-16 09:19:49 +08:00
    @aheadlead #8 master 受保护不可能直接提交代码的
    libook
        21
    libook  
       2022-05-16 10:32:29 +08:00
    上面的思路都可以参考,个人建议既然用 git 就把所有方案限定在 git 体系内,尽量不要自己复制代码。
    aheadlead
        22
    aheadlead  
       2022-05-16 18:34:12 +08:00 via iPhone
    @unco020511 你先 checkout 一个分支提交公共代码,merge 到 master 后,两个人再从 master 创建新分支分别开发
    aheadlead
        23
    aheadlead  
       2022-05-16 18:34:44 +08:00 via iPhone
    @aheadlead 当然我并不想说这是最佳实践
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1785 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 16:37 · PVG 00:37 · LAX 08:37 · JFK 11:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.