请教各位大佬,是谁把代码给合丢了,如下图,黄色为 master:
我的猜测是 B 在合并的时候给合没了,但是有个疑问就是 B 合并的时候应该会有冲突的而不是 fast forward 的吧?最开始我只看 master 的提交以为是 A 合没了。
请大佬指点
1
gam2046 2022-07-20 16:29:23 +08:00 7
看丢失文件的 git log 是在哪次 commit 中被删除的。看这个图能看出什么呢。
|
2
skaly 2022-07-20 16:34:45 +08:00
找到分支上看合并后的代码,就知道是谁合并掉的
|
3
leavic 2022-07-20 16:52:11 +08:00
3B 的时候代码就没了,然后 4A merge 的时候没审核呗。
|
4
wolfie 2022-07-20 17:08:34 +08:00
JB 家的
1. 文件 show history 2. 文件内某个段落 show history for selection |
5
lanceli 2022-07-20 17:13:49 +08:00
同遇到过
merge 时丢弃掉的,show history 里面没有记录,尴尬 |
6
JasonLaw 2022-07-20 17:18:41 +08:00 via iPhone
听不懂😅 不会只有我一个人吧?
|
7
topsy 2022-07-20 17:26:39 +08:00
猜测
1A ,2A 代码正常的话,就是 3B 合并代码导致的代码丢失,所以 4A 合 3B 的时候也丢失了 |
8
HannibaI 2022-07-20 17:29:48 +08:00
3B 处理冲突时,把代码搞丢了,这就形成了一个「删除某些代码」的 commit ,这个 commit 周围在 A 上面没人再修改过了,那 3B 合并到 A 的时候,自然而然就把 A 上相应代码也删除了。
|
9
HannibaI 2022-07-20 17:30:32 +08:00
> A 会从 B 的分支上合并到 master
|
11
HannibaI 2022-07-20 17:31:29 +08:00
这是你们分支管理混乱造成的
|
12
4771314 2022-07-20 17:33:47 +08:00
看每次 merge 的改动就可以了,看这个 graph 没有太大的用
|
14
rbe 2022-07-20 17:36:51 +08:00
尝试下 git bisect 二分查找,看丢失的代码在哪一个 commit 里
|
15
magic3584 OP |
16
magic3584 OP @HannibaI #11
每个人有个开发分支,然后都往 master 上合。不知道您说的分支管理是指的什么?所有人都在 dev 上吗? |
17
lokya 2022-07-20 17:39:48 +08:00
merge 的时候看到不是自己的 估计给舍弃了
|
18
magic3584 OP |
20
m1ng 2022-07-20 17:43:13 +08:00
git log -p <你要查看的文件路径> 可以查看文件的修改历史
|
21
ddch1997 2022-07-20 17:43:31 +08:00
单个文件不是有 git file history 吗,挨个检查
|
22
magic3584 OP |
23
imycc 2022-07-20 17:45:39 +08:00
应该是 3B 的时候把冲突的代码删掉了。
假设 A 是 master ,B 是 feature 分支。当主分支更新之后,B 把 master 上的变更 merge 过来,然后遇到冲突并解决,然后再合并回去 master ,这个时候冲突就没了。 有些脑溢血瞬间是这样的,同事 A 跟 B 改了一个功能,A 的功能已经上线,B 在解决冲突的时候删多了,测自己的功能没问题,如果没有回归测试 /集成测试,等上线 A 改的东西就挂了。 |
25
magic3584 OP |
26
HankLu 2022-07-20 19:35:53 +08:00
好麻烦啊,怎么会这么难搞
|
27
DeWjjj 2022-07-20 19:42:33 +08:00
别直接怀疑 3b ,有可能是其他线路 的提交和 3b 冲突了,直接合掉了。
3b 只是你查出来最文件消失的位置,这个时候就各自回滚。 |
28
DeWjjj 2022-07-20 19:44:32 +08:00
话说你们领导没人 review 直接合并也是权限开放的太大了。。。。。
|
30
L0L 2022-07-20 20:10:14 +08:00
3B 那个分支没有;有没有可能是不是 A 的代码没有 rebase 到 3B 的那个分支呢?
|
31
loveyu 2022-07-20 20:41:57 +08:00
上次遇到丢代码是有人 merge 有人 rebase
|
32
m1ng 2022-07-20 20:44:34 +08:00
@magic3584 你可以直接 git log -p <filename> > a.diff ,把这个文件的所有修改记录都到导出到一个文件里,然后在这个文件里搜索被删除的代码
|
33
prudence 2022-07-20 23:32:02 +08:00
合并的人冲突不解决,闭着眼选一个。就导致这样而且不容易看出
|
34
bojackhorseman 2022-07-20 23:53:22 +08:00 via iPhone
git reflog
|
35
leimao 2022-07-20 23:56:31 +08:00
3B 里的人把代码丢了呗
|
36
binux 2022-07-20 23:57:54 +08:00 via Android
master 上只要不删 commit ,挨个找呗。
|
37
rpman 2022-07-21 00:32:11 +08:00
所以高度耦合的功能少搞分支
|
38
p1gd0g 2022-07-21 00:36:52 +08:00
下个小乌龟,就能看到了
我上次也是这样,在 vscode 和 gitlab 里怎么找都看不出来,同事的小乌龟很清楚的能看到合并时的删除文件记录。具体也没细查 |
39
realpg 2022-07-21 04:29:05 +08:00
对 git 不精通不建议全在分支工作
还是建议搞 pr merge branch 有冲突只由一两个大佬操作 |
40
msg7086 2022-07-21 04:40:10 +08:00
3B 这个 merge commit ,如果是 clean merge 的话是不会有问题的。
但是如果有冲突,然后解决冲突的人乱选,就会把代码覆盖掉了。 (所以老老实实 rebase 多香。) |
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. |
42
Helsing 2022-07-21 08:26:27 +08:00 via iPhone
看 merge 记录
|
43
jheroy 2022-07-21 09:07:41 +08:00
git log -S [string] ./file
git log -G [regex] ./file string 和 regex 是被删哪行的内容或者正则表达式, 看最后是谁提交的就行. |
44
guanhui07 2022-07-21 09:26:12 +08:00
我也是 JB 家的
文件 show history 一个个 commit 看 以及重点看 merge 才能看出来 |
45
creanme 2022-07-21 09:33:17 +08:00
我也遇到过几次,同事合并代码提交上来我代码就少了一部分,但是呢看 commit 文件变动,又没改动我的代码部分。
|
46
jimmyismagic 2022-07-21 09:41:15 +08:00
master 合并设置权限,只允许 rebase fast forward 合并,一条线清清楚楚
|
47
KaGaMiKun 2022-07-21 10:00:14 +08:00
看着应该是 B 分支本来没有 A 分支文件,在 1A 后合了一次到 B
|
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 |
49
ypzhou 2022-07-21 10:34:40 +08:00
我碰到过,他拉取不下来,有冲突,然后直接给你强制提交他本地的。
|
50
justNoBody 2022-07-21 10:40:10 +08:00
@GeruzoniAnsasu #41 引用的文章,我觉得说的不对。正如文章下面有人评论的,在多人开发的时候,如果 feature1 先行合并到了 dev 分支,feature2 在合并到 dev 分支时,遇到合并冲突是非常常见的一件事,这个时候,就需要把 dev 的代码合并到 feature2 中。
我理解 OP 这个问题,应该是合并代码的那个人搞丢的,把合并的那个节点提交找出来看看,是不是就可以定位到具体是谁合并丢了? |
51
Felldeadbird 2022-07-21 10:50:10 +08:00
4A 和 3B 他们各自合并? 看 log 找 commit 记录 对比一起。肯定有人解决冲突时,删掉了代码。
|
52
SelFree 2022-07-21 10:54:04 +08:00
--full-history
|
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 的时候这个地方根本就没有冲突产生。 |
54
bertonzh 2022-07-21 11:22:49 +08:00
以上 #53 有 typo ,3D -> 3B
|
55
lonenol 2022-07-21 13:53:09 +08:00
猜测是 3B 在解决冲突的时候把代码搞丢了
|
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.
|
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 上的东西。 ----- 我看很多人在说解决冲突时误删了代码,然而并不是这么回事。更要命的是搞清并向每一个人说明原理实在是太难了。所以直接制定规则是最可靠科学的办法 |
58
tuutoo 2022-07-21 14:21:25 +08:00
哪个文件的代码丢了 看这个文件的 commit log 是在哪个 commit 丢掉的.
可以只看一个文件的 找到这个 commit 了 你不就找到人了. |
59
shm7 2022-07-21 15:57:22 +08:00
从前一次的 commit point 重新牵出来代码吧,再手工整合进去。
|
60
Hawthorne 2022-07-21 16:20:43 +08:00 via Android
如果代码没修改过不会有冲突,也可能冲突时选择了使用自己的(如果是 sourcetree 等工具也可能选错)。
如果被删的是文件,看历史是哪个提交删除的,如果是内容就先找到文件再看文件的历史。 |
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 |
62
dablwow 2022-07-21 17:48:19 +08:00
@dablwow #61 所以,楼主查看最早丢代码的 commit 的思路是对的,只是不能通过 diff 的"-B"去判断,而是要找"没有+B"的 diff
|
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 里,更容易排查问题 |
65
preper 2022-07-22 17:13:47 +08:00
@magic3584 因为 merge 的时候产生冲突了,这时未冲突的文件( file2 )在暂存区,冲突文件( file1 )解决冲突后也会放到暂存区,然后 merge --continue ,merge 结束。但如果解决冲突的人把未冲突的文件( file2 )从暂存区移除了(码农 os:我靠这代码不是我写的,为啥会有这个提交?删掉删掉!),导致
|
66
preper 2022-07-22 17:16:29 +08:00
@preper 导致 merge --continue 之后没有提交 file2 ,结果别人 file2 的修改就被顶掉了。最恶心的是这种修改不会体现在文件的 history 里,查看文件修改的 history 找不到文件回滚的原因,只能在指定的 merge commit 信息里看到文件的改动。所以我跟很多同事都推荐过,解决冲突尽量依靠 rebase 解决,这样冲突解决错误了还能在普通 commit 里追溯
|
67
preper 2022-07-22 17:21:13 +08:00
>>> 把未冲突的文件( file2 )从暂存区移除了
这个步骤也有可能是在 git 的某些 GUI 中没有提交对应的修改导致的 |