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

请教一下,是谁把代码合丢了

  •  
  •   magic3584 · 2022-07-20 16:25:36 +08:00 · 10765 次点击
    这是一个创建于 849 天前的主题,其中的信息可能已经有所发展或是发生改变。

    请教各位大佬,是谁把代码给合丢了,如下图,黄色为 master:

    img

    我的猜测是 B 在合并的时候给合没了,但是有个疑问就是 B 合并的时候应该会有冲突的而不是 fast forward 的吧?最开始我只看 master 的提交以为是 A 合没了。

    请大佬指点

    1. 到底是谁给合没了
    2. 这个图看着确实不知道怎么去找是谁?请问是否有更清晰的图?
    3. 为什么 A 会从 B 的分支上合并到 master
    第 1 条附言  ·  2022-07-20 18:52:48 +08:00
    还有个奇怪的问题
    我 show history 的时候

    第一次 commit:
    --- log(1)
    +++ log(2)

    第二次 commit:
    --- log(1)

    疑问:
    第二次不应该是 ---log(2) 吗
    第 2 条附言  ·  2022-07-22 14:59:40 +08:00
    3B 的时候把我代码合丢了好多,吐血了。。。
    68 条回复    2022-07-22 17:28:43 +08:00
    gam2046
        1
    gam2046  
       2022-07-20 16:29:23 +08:00   ❤️ 7
    看丢失文件的 git log 是在哪次 commit 中被删除的。看这个图能看出什么呢。
    skaly
        2
    skaly  
       2022-07-20 16:34:45 +08:00
    找到分支上看合并后的代码,就知道是谁合并掉的
    leavic
        3
    leavic  
       2022-07-20 16:52:11 +08:00
    3B 的时候代码就没了,然后 4A merge 的时候没审核呗。
    wolfie
        4
    wolfie  
       2022-07-20 17:08:34 +08:00
    JB 家的
    1. 文件 show history
    2. 文件内某个段落 show history for selection
    lanceli
        5
    lanceli  
       2022-07-20 17:13:49 +08:00
    同遇到过
    merge 时丢弃掉的,show history 里面没有记录,尴尬
    JasonLaw
        6
    JasonLaw  
       2022-07-20 17:18:41 +08:00 via iPhone
    听不懂😅 不会只有我一个人吧?
    topsy
        7
    topsy  
       2022-07-20 17:26:39 +08:00
    猜测
    1A ,2A 代码正常的话,就是 3B 合并代码导致的代码丢失,所以 4A 合 3B 的时候也丢失了
    HannibaI
        8
    HannibaI  
       2022-07-20 17:29:48 +08:00
    3B 处理冲突时,把代码搞丢了,这就形成了一个「删除某些代码」的 commit ,这个 commit 周围在 A 上面没人再修改过了,那 3B 合并到 A 的时候,自然而然就把 A 上相应代码也删除了。
    HannibaI
        9
    HannibaI  
       2022-07-20 17:30:32 +08:00
    > A 会从 B 的分支上合并到 master
    NoKey
        10
    NoKey  
       2022-07-20 17:31:05 +08:00
    @lanceli 总会有记录可查吧
    HannibaI
        11
    HannibaI  
       2022-07-20 17:31:29 +08:00
    这是你们分支管理混乱造成的
    4771314
        12
    4771314  
       2022-07-20 17:33:47 +08:00
    看每次 merge 的改动就可以了,看这个 graph 没有太大的用
    magic3584
        13
    magic3584  
    OP
       2022-07-20 17:36:49 +08:00
    @gam2046 #1
    大佬,git log 是人为打上的,这个怎么能看到代码是在哪丢的呢?
    rbe
        14
    rbe  
       2022-07-20 17:36:51 +08:00
    尝试下 git bisect 二分查找,看丢失的代码在哪一个 commit 里
    magic3584
        15
    magic3584  
    OP
       2022-07-20 17:37:54 +08:00
    @wolfie #4
    @lanceli #5
    我用的 fork ,show history 应该只能显示当前分支的历史。我是想找出谁给合没的
    magic3584
        16
    magic3584  
    OP
       2022-07-20 17:38:53 +08:00
    @HannibaI #11
    每个人有个开发分支,然后都往 master 上合。不知道您说的分支管理是指的什么?所有人都在 dev 上吗?
    lokya
        17
    lokya  
       2022-07-20 17:39:48 +08:00
    merge 的时候看到不是自己的 估计给舍弃了
    magic3584
        18
    magic3584  
    OP
       2022-07-20 17:40:03 +08:00
    @4771314 #12

    @rbe #14
    看提交是 3B 就没了,merge 到 master 是 4A 没有了,所以我搞不懂到底是谁搞没的
    magic3584
        19
    magic3584  
    OP
       2022-07-20 17:41:42 +08:00
    @lanceli #5
    我这已经是第二次被合丢代码了,测试找过来的时候我清楚记得自己是写过的。。。
    m1ng
        20
    m1ng  
       2022-07-20 17:43:13 +08:00
    git log -p <你要查看的文件路径> 可以查看文件的修改历史
    ddch1997
        21
    ddch1997  
       2022-07-20 17:43:31 +08:00
    单个文件不是有 git file history 吗,挨个检查
    magic3584
        22
    magic3584  
    OP
       2022-07-20 17:44:06 +08:00
    @HannibaI #8
    我们是每人一个分支,然后都往 master 上合。

    “ A 会从 B 的分支上合并到 master”
    这句我没看懂。A 不是只有自己的分支和 master 吗
    imycc
        23
    imycc  
       2022-07-20 17:45:39 +08:00
    应该是 3B 的时候把冲突的代码删掉了。

    假设 A 是 master ,B 是 feature 分支。当主分支更新之后,B 把 master 上的变更 merge 过来,然后遇到冲突并解决,然后再合并回去 master ,这个时候冲突就没了。

    有些脑溢血瞬间是这样的,同事 A 跟 B 改了一个功能,A 的功能已经上线,B 在解决冲突的时候删多了,测自己的功能没问题,如果没有回归测试 /集成测试,等上线 A 改的东西就挂了。
    gam2046
        24
    gam2046  
       2022-07-20 17:53:55 +08:00
    @magic3584 #13 git log -p <filename>
    magic3584
        25
    magic3584  
    OP
       2022-07-20 18:40:51 +08:00
    @m1ng #20
    @ddch1997 #21
    @gam2046 #24
    git log -p <filename> 我这命令行循环显示最近的俩 commit
    HankLu
        26
    HankLu  
       2022-07-20 19:35:53 +08:00
    好麻烦啊,怎么会这么难搞
    DeWjjj
        27
    DeWjjj  
       2022-07-20 19:42:33 +08:00
    别直接怀疑 3b ,有可能是其他线路 的提交和 3b 冲突了,直接合掉了。
    3b 只是你查出来最文件消失的位置,这个时候就各自回滚。
    DeWjjj
        28
    DeWjjj  
       2022-07-20 19:44:32 +08:00
    话说你们领导没人 review 直接合并也是权限开放的太大了。。。。。
    magic3584
        29
    magic3584  
    OP
       2022-07-20 19:52:00 +08:00
    @DeWjjj #27
    所以找不出来到底谁改了吗?
    小公司,都能合 master 就看出来了
    L0L
        30
    L0L  
       2022-07-20 20:10:14 +08:00
    3B 那个分支没有;有没有可能是不是 A 的代码没有 rebase 到 3B 的那个分支呢?
    loveyu
        31
    loveyu  
       2022-07-20 20:41:57 +08:00
    上次遇到丢代码是有人 merge 有人 rebase
    m1ng
        32
    m1ng  
       2022-07-20 20:44:34 +08:00
    @magic3584 你可以直接 git log -p <filename> > a.diff ,把这个文件的所有修改记录都到导出到一个文件里,然后在这个文件里搜索被删除的代码
    prudence
        33
    prudence  
       2022-07-20 23:32:02 +08:00
    合并的人冲突不解决,闭着眼选一个。就导致这样而且不容易看出
    bojackhorseman
        34
    bojackhorseman  
       2022-07-20 23:53:22 +08:00 via iPhone
    git reflog
    leimao
        35
    leimao  
       2022-07-20 23:56:31 +08:00
    3B 里的人把代码丢了呗
    binux
        36
    binux  
       2022-07-20 23:57:54 +08:00 via Android
    master 上只要不删 commit ,挨个找呗。
    rpman
        37
    rpman  
       2022-07-21 00:32:11 +08:00
    所以高度耦合的功能少搞分支
    p1gd0g
        38
    p1gd0g  
       2022-07-21 00:36:52 +08:00
    下个小乌龟,就能看到了
    我上次也是这样,在 vscode 和 gitlab 里怎么找都看不出来,同事的小乌龟很清楚的能看到合并时的删除文件记录。具体也没细查
    realpg
        39
    realpg  
       2022-07-21 04:29:05 +08:00
    对 git 不精通不建议全在分支工作
    还是建议搞 pr
    merge branch 有冲突只由一两个大佬操作
    msg7086
        40
    msg7086  
       2022-07-21 04:40:10 +08:00
    3B 这个 merge commit ,如果是 clean merge 的话是不会有问题的。
    但是如果有冲突,然后解决冲突的人乱选,就会把代码覆盖掉了。
    (所以老老实实 rebase 多香。)
    GeruzoniAnsasu
        41
    GeruzoniAnsasu  
       2022-07-21 07:13:46 +08:00   ❤️ 1
    https://www.jianshu.com/p/603186352605

    严禁双向 merge. 3B 做了一个从其它分支 merge 的操作,万恶之源。


    虽然


    但是还是强烈建议你们设定「严禁自己分支 merge 其它分支」的规则。
    要临时合并其他人的工作只允许 rebase/cherry-pick ,

    严禁双向 merge.
    Helsing
        42
    Helsing  
       2022-07-21 08:26:27 +08:00 via iPhone
    看 merge 记录
    jheroy
        43
    jheroy  
       2022-07-21 09:07:41 +08:00
    git log -S [string] ./file
    git log -G [regex] ./file
    string 和 regex 是被删哪行的内容或者正则表达式, 看最后是谁提交的就行.
    guanhui07
        44
    guanhui07  
       2022-07-21 09:26:12 +08:00
    我也是 JB 家的
    文件 show history 一个个 commit 看 以及重点看 merge 才能看出来
    creanme
        45
    creanme  
       2022-07-21 09:33:17 +08:00
    我也遇到过几次,同事合并代码提交上来我代码就少了一部分,但是呢看 commit 文件变动,又没改动我的代码部分。
    jimmyismagic
        46
    jimmyismagic  
       2022-07-21 09:41:15 +08:00
    master 合并设置权限,只允许 rebase fast forward 合并,一条线清清楚楚
    KaGaMiKun
        47
    KaGaMiKun  
       2022-07-21 10:00:14 +08:00
    看着应该是 B 分支本来没有 A 分支文件,在 1A 后合了一次到 B
    KaGaMiKun
        48
    KaGaMiKun  
       2022-07-21 10:03:18 +08:00
    看着应该是 B 分支本来没有 A 分支文件,在 1A 后合了一次到 B
    可能因为冲突,没有合并到 A 的新文件,导致 B 分支上缺少了文件
    并且在 3B 合并时已经处理 A->B 的冲突,所以没有出现冲突处理,导致直接覆盖了 A 分支

    所以问题最初应该在 1A 后 2A 前,B 分支合并 A 分支时冲突没有处理好发生的

    (不小心按到了 ctrl 发多了一楼 XD
    ypzhou
        49
    ypzhou  
       2022-07-21 10:34:40 +08:00
    我碰到过,他拉取不下来,有冲突,然后直接给你强制提交他本地的。
    justNoBody
        50
    justNoBody  
       2022-07-21 10:40:10 +08:00
    @GeruzoniAnsasu #41 引用的文章,我觉得说的不对。正如文章下面有人评论的,在多人开发的时候,如果 feature1 先行合并到了 dev 分支,feature2 在合并到 dev 分支时,遇到合并冲突是非常常见的一件事,这个时候,就需要把 dev 的代码合并到 feature2 中。

    我理解 OP 这个问题,应该是合并代码的那个人搞丢的,把合并的那个节点提交找出来看看,是不是就可以定位到具体是谁合并丢了?
    Felldeadbird
        51
    Felldeadbird  
       2022-07-21 10:50:10 +08:00
    4A 和 3B 他们各自合并? 看 log 找 commit 记录 对比一起。肯定有人解决冲突时,删掉了代码。
    SelFree
        52
    SelFree  
       2022-07-21 10:54:04 +08:00
    --full-history
    bertonzh
        53
    bertonzh  
       2022-07-21 11:21:43 +08:00
    不知道我对这个图的理解对不对:
    1. 3B 是一个 merge ,而且 3B 的 parent commit 之一是 1A ;
    2. 1A 中有正常代码,但是 3B 里面没有了。

    如果我的理解正确,那么毫无疑问,是 3D 这个 merge 进行的时候,产生了冲突,然后提交者瞎搞把代码搞没了。
    至于 4A 完全是无辜的,因为相关的冲突已经被 3D 解决过,到 4A merge 的时候这个地方根本就没有冲突产生。
    bertonzh
        54
    bertonzh  
       2022-07-21 11:22:49 +08:00
    以上 #53 有 typo ,3D -> 3B
    lonenol
        55
    lonenol  
       2022-07-21 13:53:09 +08:00
    猜测是 3B 在解决冲突的时候把代码搞丢了
    whatiam
        56
    whatiam  
       2022-07-21 13:55:34 +08:00
    这里存在 2 个可以讨论的问题: 1. 代码是怎么被操作的? 回答: merge 的时候, 没有先 fetch and merge 远端, 导致覆盖掉了远端. 2. 为啥历史记录看不到? 因为 git 默认的 log 指令有简化历史功能, 这里可以使用 git log -p -m file.txt 进行查看完整历史. 其中 -p 表示 patch, m 表示 merge.
    GeruzoniAnsasu
        57
    GeruzoniAnsasu  
       2022-07-21 14:00:52 +08:00
    @justNoBody 双向 merge 的诡异之处在于,这东西会受时序影响。两个 feature 分支的分岔点如果一样,可能不会出问题,但如果一前一后各自分岔,那么 A=>B=>C 与 B=>A=>C 的结果可能就不一样而且不符合预期了。

    你也许没明白的是,双向 merge 会发生未产生冲突就丢代码的情况。

    原因是更新( new )的节点(A)merge 了一个旧节点(B)再 merge 回去(B') 会使 B'认为「不存在(B~B)'期间提交历史」的版本更新( newer ),从而丢弃(B~B')。这个情况是很难预期也不好发现的。

    所以实践上应该禁止 feature2 去 merge dev ,它完全可以 rebase dev 把自己接到后面,此时解决冲突相当于相当于不断发生 dev[N],dev[N+1],feature2[N+1]的三路合并,由于 base 点在 dev[N],所以不会丢失 dev[N]后的东西(不会认为 dev[N]前的版本更新(newer)),又因为 N 必定大于 feature1 与 dev 的分岔点( feature1 已经接到 dev 上了),所以也不会丢失 feature1 上的东西。

    -----

    我看很多人在说解决冲突时误删了代码,然而并不是这么回事。更要命的是搞清并向每一个人说明原理实在是太难了。所以直接制定规则是最可靠科学的办法
    tuutoo
        58
    tuutoo  
       2022-07-21 14:21:25 +08:00
    哪个文件的代码丢了 看这个文件的 commit log 是在哪个 commit 丢掉的.
    可以只看一个文件的
    找到这个 commit 了 你不就找到人了.
    shm7
        59
    shm7  
       2022-07-21 15:57:22 +08:00
    从前一次的 commit point 重新牵出来代码吧,再手工整合进去。
    Hawthorne
        60
    Hawthorne  
       2022-07-21 16:20:43 +08:00 via Android
    如果代码没修改过不会有冲突,也可能冲突时选择了使用自己的(如果是 sourcetree 等工具也可能选错)。

    如果被删的是文件,看历史是哪个提交删除的,如果是内容就先找到文件再看文件的历史。
    dablwow
        61
    dablwow  
       2022-07-21 17:46:32 +08:00
    搞丢代码的 commit 在 diff 上未必显示为删除,因为 merge diff 显示的是"外部 commit 相对于当前分支的改动",而不是反过来。

    举个例子,master 一开始有 A 这一行代码,然后切出个人分支;

    后面 master 新增了 B (此时代码为 A+B ),个人分支新增了 C (此时代码为 A+C )

    当个人分支 merge master 时,假设冲突正确处理,显示的 diff 是+B ,而不是+C ;
    如果冲突处理有误,把 B 搞丢了,那 diff 什么都不显示,而不是-B
    dablwow
        62
    dablwow  
       2022-07-21 17:48:19 +08:00
    @dablwow #61 所以,楼主查看最早丢代码的 commit 的思路是对的,只是不能通过 diff 的"-B"去判断,而是要找"没有+B"的 diff
    preper
        63
    preper  
       2022-07-22 15:32:52 +08:00
    这种 merge 丢代码问题一般是解决冲突解决的不对,解决冲突时把某些应该 merge 进去的改动抛弃掉了,再合进去就会导致代码丢失。具体错误操作流程可以参考 juejin.cn/post/6844903511453335559
    没想到这个问题意外的经常会看到。导致这个问题的原因,除了解决冲突的人对 git 理解不深之外,团队的 git 工作流可能也有问题。建议 merge 产生冲突的时候,不要直接解决 merge 的冲突,而是 merge --abort 然后 rebase 主分支来解决冲突,这样解决冲突后的代码在 commit 里而不是在 merge 里,更容易排查问题
    magic3584
        64
    magic3584  
    OP
       2022-07-22 16:54:40 +08:00
    @preper #63
    看了下链接,对第 3 步有点不解。3 没有修改 file2 ,会啥 file2 会丢失呢
    preper
        65
    preper  
       2022-07-22 17:13:47 +08:00
    @magic3584 因为 merge 的时候产生冲突了,这时未冲突的文件( file2 )在暂存区,冲突文件( file1 )解决冲突后也会放到暂存区,然后 merge --continue ,merge 结束。但如果解决冲突的人把未冲突的文件( file2 )从暂存区移除了(码农 os:我靠这代码不是我写的,为啥会有这个提交?删掉删掉!),导致
    preper
        66
    preper  
       2022-07-22 17:16:29 +08:00
    @preper 导致 merge --continue 之后没有提交 file2 ,结果别人 file2 的修改就被顶掉了。最恶心的是这种修改不会体现在文件的 history 里,查看文件修改的 history 找不到文件回滚的原因,只能在指定的 merge commit 信息里看到文件的改动。所以我跟很多同事都推荐过,解决冲突尽量依靠 rebase 解决,这样冲突解决错误了还能在普通 commit 里追溯
    preper
        67
    preper  
       2022-07-22 17:21:13 +08:00
    >>> 把未冲突的文件( file2 )从暂存区移除了
    这个步骤也有可能是在 git 的某些 GUI 中没有提交对应的修改导致的
    magic3584
        68
    magic3584  
    OP
       2022-07-22 17:28:43 +08:00
    @preper #65
    我一直用的 GUI ,冲突的显示 unstaged ,未冲突都是 staged ,我也没有手动去暂存区删过东西。

    我之前只看 master 所以以为是 4A 搞丢的,但实际上,3B 从 1A 合并解决的时候已经搞丢了,只不过 4A 后来又合并了一下。
    结论应该是 3B 给搞丢的,不知道我理解的是否正确呢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2796 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 11:45 · PVG 19:45 · LAX 03:45 · JFK 06:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.