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

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

  •  
  •   magic3584 · 74 天前 · 9182 次点击
    这是一个创建于 74 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    img

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

    请大佬指点

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

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

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

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

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

    “ A 会从 B 的分支上合并到 master”
    这句我没看懂。A 不是只有自己的分支和 master 吗
    imycc
        23
    imycc  
       74 天前
    应该是 3B 的时候把冲突的代码删掉了。

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

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

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


    虽然


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

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

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

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

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

    如果我的理解正确,那么毫无疑问,是 3D 这个 merge 进行的时候,产生了冲突,然后提交者瞎搞把代码搞没了。
    至于 4A 完全是无辜的,因为相关的冲突已经被 3D 解决过,到 4A merge 的时候这个地方根本就没有冲突产生。
    bertonzh
        54
    bertonzh  
       73 天前
    以上 #53 有 typo ,3D -> 3B
    lonenol
        55
    lonenol  
       73 天前
    猜测是 3B 在解决冲突的时候把代码搞丢了
    whatiam
        56
    whatiam  
       73 天前
    这里存在 2 个可以讨论的问题: 1. 代码是怎么被操作的? 回答: merge 的时候, 没有先 fetch and merge 远端, 导致覆盖掉了远端. 2. 为啥历史记录看不到? 因为 git 默认的 log 指令有简化历史功能, 这里可以使用 git log -p -m file.txt 进行查看完整历史. 其中 -p 表示 patch, m 表示 merge.
    GeruzoniAnsasu
        57
    GeruzoniAnsasu  
       73 天前
    @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  
       73 天前
    哪个文件的代码丢了 看这个文件的 commit log 是在哪个 commit 丢掉的.
    可以只看一个文件的
    找到这个 commit 了 你不就找到人了.
    shm7
        59
    shm7  
       73 天前
    从前一次的 commit point 重新牵出来代码吧,再手工整合进去。
    Hawthorne
        60
    Hawthorne  
       73 天前 via Android
    如果代码没修改过不会有冲突,也可能冲突时选择了使用自己的(如果是 sourcetree 等工具也可能选错)。

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

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