GIT 冲突的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生的内容
codingKingKong
V2EX    程序员

GIT 冲突的问题

  •  
  • /div>   codingKingKong
    isCoding 2018-09-17 15:54:06 +08:00 3197 次点击
    这是一个创建于 2584 天前的主题,其中的信息可能已经有所发展或是发生改变。

    刚才发生了一个问题, 我有 2 个分支, 由 A 分支向 B 分支做 PR 的时候, 报了冲突, 而我反向由 B 向 A 做的时候, 就成功了, 为什么呢?

    20 条回复    2018-09-20 16:13:41 +08:00
    iSecret
        1
    iSecret  
       2018-09-17 16:35:59 +08:00
    B 分支是从 A 分支拉出来的吧?如果 A 分支有其他提交或者合并没有向 B 分支合并的话是可能会出现冲突的。
    PazuLee
        2
    PazuLee  
       2018-09-17 16:36:57 +08:00
    commit 顺序,也可能有影响
    codingKingKong
        3
    codingKingKong  
    OP
       2018-09-17 16:41:23 +08:00
    @iSecret A 是由 B 拉出来的, 在 A 开发的过程中, 队友向 B 做了 PR, 我 A 向 B 做 PR 的时候, 就冲突了, 但是我反向 BA 的时候, 就 success 了...
    codingKingKong
        4
    codingKingKong  
    OP
       2018-09-17 16:41:47 +08:00
    @PazuLee 有没有 commit 顺序对这个影响的文章可以研究一下?
    PazuLee
        5
    PazuLee  
       2018-09-17 16:46:50 +08:00
    @codingKingKong 这个还真没有,经验之谈~另外 A&B 之间有 master 分支么~如果没有的话,可以找找现在 git 比较流行的开发分支模型,应该能减少一些冲突概率吧
    msg7086
        6
    msg7086  
       2018-09-18 05:14:32 +08:00
    Merge 的时候,A 向 B merge 是把分叉点到 A 的更改做成补丁打到 B 上。
    B 向 A merge 是反过来,把 B 的更改做成补丁打到 A 上,具体的算法实现是不一样的。

    另外我们的习惯是做 rebase 后再 merge 回去。
    非 clean 的 merge 会导致 conflict resolving 产生的更改被隐藏在 merge commit 里,无法追溯。
    我们实际遇到过这问题,feature commits 和 merge 后的 tree 内容不同,后来发现是 merge commit 里有人做了额外的修改。

    Git 你要是闭着眼睛颠来倒去尝试,看哪个能跑通就用哪个跑,那这个 repo 没过多久就得乱成炸酱面了。
    k19870203
        7
    k19870203  
       2018-09-18 09:14:26 +08:00
    @msg7086 你说的是 rebase 吧,merge 是三方合并,解决冲突的提交也是一次提交,为啥没法追溯呢?
    msg7086
        8
    msg7086  
       2018-09-18 09:42:50 +08:00
    @k19870203 是 3-way merge,但是 apply diff 的顺序是不一样的吧。先 apply A-O 再 apply B-O,还是反过来,可能就会影响冲突判定了。

    至于解决冲突,因为解决冲突本身是包含在 Merge commit 里,实际上一般不会有人特意去写这次 Merge conflict 到底改了哪些部分,甚至都不会说这个 Merge 做过了额外的修改,所以追溯的时候就会出现一个没有修改说明的修改。可能合并前测通了,合并后崩了,然后你发现是 Merge 的时候有人改错代码了。
    codingKingKong
        9
    codingKingKong  
    OP
       2018-09-18 10:14:34 +08:00
    @PazuLee 啊, 感谢, 其实是我队友的问题, 我实际不是这样操作的~只是用 AB 做了模拟
    Eoston
        10
    Eoston  
       2018-09-18 10:17:23 +08:00
    我们每个人自己的分支都是从远端 dev 分支拉出来的,然后正常情况应该是自己的分支修改后 commit-push 到自己的分支,然后需要把 dev 分支拉一下最新修改,再把 dev merge 到自己分支,然后自己分支再 merge 到 dev 分支。。。。结果有同事把 dev 拉到本地后,自己分支修改了,但自己分支的代码比较老了,就直接把本地 dev 分支 merge 到自己分支,然后又 merge 回了 dev 分支并且 push 了。。。。不知道是如何 push 成功的。。。结果把我们之前的所有修改全部冲掉了!!!!!害的我们废了老长时间重新修改了回去……
    codingKingKong
        11
    codingKingKong  
    OP
       2018-09-18 10:20:26 +08:00
    @msg7086 啊, 我目前的做法是 feature merge into release, 产生冲突解决会写改动, 不过大部分服务是我一个人维护, 都还好, ABmerge 方向不同, 使用的算法不同这点, 会导致结果不同么? 另: 做 rebase 的时候, 你们是 feature onto release,然后再 merge 的这步, merge 方向是怎样的呢?

    PS:feature 是我自己的新功能分支, release 作为大家共同编辑的分支~
    codingKingKong
        12
    codingKingKong  
    OP
       2018-09-18 10:24:08 +08:00
    @Eoston 通过 checkout 某一个正确的提交恢复后, 强行 push 回去, 可以解决这个问题么? 如果之前的 commit 没有被覆盖的情况下.
    codingKingKong
        13
    codingKingKong  
    OP
       2018-09-18 10:26:18 +08:00
    @Eoston 啊, 成功可能是因为本地认为 dev 已经是最新的了, 队友做 A 向 dev merge 的时候, 当成了更改吧.或者如果队友使用了 source tree, 会有丢弃更改的功能, 踩过一次坑
    msg7086
        14
    msg7086  
       2018-09-18 10:41:56 +08:00
    @codingKingKong
    AB merge 方向这个我也不是很清楚,但是如果本身没冲突的话 3-way merge 完的结果应该是一样的。有冲突的情况下,可能先合并的更改会改变后续更改的参考系,所以可能会产生结果不一致。

    至于项目管理的话,我们一般是一个 feature 一个分支。一旦某个 feature 定稿合并以后,其他 feature 分支需要 rebase 到 tip 上然后才能 merge。

    所以我们的分支图大致是这样的:



    以及之前的反面教材:



    (不知道你能不能看到图。)

    另外 force-push 一般是不会丢 commit 的,只要之前那个正常 push 的人重建分支就行了,很简单的。
    用 Git 这种多人协作工具,一定要保证每个人都会用 Git,然后才能放进来做贡献。之前我进公司以后看到公司里十来个完全不懂 Git 怎么用的人,真的是心态爆炸。
    sampeng
        15
    sampeng  
       2018-09-18 16:11:15 +08:00 via iPhone
    @Eoston 版本控制…只要你们找到他 push 的点。全部给剔除掉后面的提交。就行了…重新写一遍代码?疯啦?
    codingKingKong
        16
    codingKingKong  
    OP
       2018-09-19 10:36:51 +08:00
    @msg7086 感谢回复. 我看了你的图, 你们的 tip 分支是作为什么样的角色存在的呢? 是每人在自己的 feature 开发, 然后 rebase 到 tip, tip 有更新后 rebase 完 merge tip 到自己的 feature 继续开发, 要发版时, 由 tip 创建 release 发版. 这样的一个流程么?
    msg7086
        17
    msg7086  
       2018-09-19 16:24:38 +08:00   1
    @codingKingKong 「 tip 」指的是每个分支的顶端(或者说末端)。
    rebase 到 tip 上,也就是 rebase 到 master/dev 的最新提交,然后再做 feature->master/dev 的 merge。

    比如 dev 是 9/1 提交的,9/1-9/20,两个人 A 和 B 分别开发了两个不同的 feature。
    A 现在要合并 A 分支,当然是没问题的。
    然后 B 要合并的时候,我们要求 B 需要先 rebase 到合并完 A 的主线的最新提交,然后才允许 B 合并。
    codingKingKong
        18
    codingKingKong  
    OP
       2018-09-20 14:24:11 +08:00
    @msg7086 我大概看懂了, 不知道你们有没有遇到这样的情况, 在 AB 都 merge 完之后, 由于排期更改, A 需求暂定不随着下次发版发出去了, 这个时候 B rebase 过来的 commit 会不会带上了 A 的 feature 呢? 如何保证的下次发版仅包含 B 的 feature 的呢?
    msg7086
        19
    msg7086  
       2018-09-20 15:26:36 +08:00
    @codingKingKong 原则上我们只有决定要上线的功能才 Merge。
    你想呀,因为 A 和 B 随时都跟随着 tip,所以 AB 自己的 tip 就是 dev+feature 的,只要跑通测试,任何时候都可以 Merge 进 dev。如果研究决定新版本只留 B 不留 A,那 A 就留到发布以后再 Merge 就行了。

    就算 A 和 B 已经 Merge 了,想要剔出 A 当然也是可以的,两种做法。

    1. 非处 x 女座:把 A 分支整个 Revert 掉,作为单个提交放在 tip 上。
    Old -> Merge A -> Merge B -> Revert Merge A <- release-x.x

    2. 处 x 女座:把历史记录重写掉
    Old -> Merge A -> Merge B <- dev tip
    首先把 dev reset hard 回 Old,然后把 B 重新 rebase 回 Old,再 Merge 回 dev,变成
    Old -> Merge B <- dev tip
    ...\--->a1->a2->a3 <- A
    然后把 A 和 dev 强推回仓库,再让每个人 fetch 一下就行了。

    第二种做法要求大家都懂 Git,如果有人不会,还是用方法 1 好了。

    如果用的是推荐的 Git flow 流程,也就是 master 部署,而 dev 开发的话,最差也就是重建 dev 分支,Rebase feature branch 然后重新 Merge 而已。Git 本身是很灵活的,怎么玩都行……
    codingKingKong
        20
    codingKingKong  
    OP
       2018-09-20 16:13:41 +08:00
    @msg7086 啊, 好的, 谢谢~ 果然是很灵活, 了解了另外一种思路.
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4389 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 10:11 PVG 18:11 LAX 03:11 JFK 06:11
    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