相关文章推荐
机灵的莲藕  ·  DevOps - Git ...·  4 周前    · 
傻傻的甘蔗  ·  处理.git文件夹过大出现臃肿问题-filt ...·  4 周前    · 
文武双全的灭火器  ·  Git合并冲突处理指南:解决二进制文件冲突_ ...·  3 周前    · 
踏实的碗  ·  浅谈HASH长度拓展攻击 - ...·  1 年前    · 
伤情的莴苣  ·  react.js - ...·  1 年前    · 
爱吹牛的大熊猫  ·  PyCharm远程调试代码 - 知乎·  2 年前    · 
挂过科的爆米花  ·  Python获取输入:sys.stdin与i ...·  2 年前    · 
Code  ›  【消失的代码】Git 合并分支导致代码消失开发者社区
git
https://cloud.tencent.com/developer/article/2033888
纯真的鸵鸟
1 年前
用户1097444
0 篇文章

【消失的代码】Git 合并分支导致代码消失

前往专栏
腾讯云
开发者社区
文档 意见反馈 控制台
首页
学习
活动
专区
工具
TVP
最新优惠活动
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
用户1097444
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
社区首页 > 专栏 > 腾讯IMWeb前端团队 > 【消失的代码】Git 合并分支导致代码消失

【消失的代码】Git 合并分支导致代码消失

作者头像
用户1097444
发布 于 2022-06-29 15:05:52
2.6K 0
发布 于 2022-06-29 15:05:52
举报

1. 问题背景

A 页面的代码莫名其妙消失了,而且不清楚是什么时候被删的。

发现这个问题之后,心里除了一句“草泥马”以外,也萌生了很多疑惑。比如说,团队在代码上线前,是有 CR 流程的,为什么这个代码消失的 commit 会逃过这么多高工的法眼?

我们希望能找回代码,并查出是哪次 commit 涉及到的,进而找出操作过程,以防后续再有人出现类似操作。

2. 处理方式

2.1 通过 git log 查找出修改过指定文件的 commit

目前文件已经被删除了,但是根据项目的代码结构,可以推测出原本是存在 A/index.js 这个文件的。

尝试检测一下在所有历史记录中,对该文件的处理,用到的命令如下:

git log --stat --full-history --simplify-merges -- A/index.js

上述命令将会展示涉及到该文件更改的 commit,从输出结果我们可以看到,在 fix:1 这个 commit 中,删了 200 行代码,而之后就再没有 commit 处理过该文件了,所以可以推测文件就是在这个 commit 中被删除了。

然后通过 git checkout 6df716248794c3c54873f73002b8bd0854ac0805,去到删除操作前最后修改过该文件的的 commit,即可拿到被删除前的代码了。

2.2. 解释一下命令及每个参数的作用

2.2.1. git log 查看对指定文件修改过的commit
git log -- A/index.js

只使用上述命令去查找文件历史,会存在一个问题:如果文件目前不存在,则什么记录都没有。

既然如此,我们先把代码恢复,再看看会展示什么:

上图可以看到,只有恢复之后的那次 commit 的记录。删除代码、以及删除代码前对该文件的所有 commit 都不会展示出来。这又是为什么呢?

这是因为 git log 的一个默认策略:

也就是默认模式下,git log 会简化文件历史,如果一些分支合起来看之后的结果是相同的,就不会展示这些分支。

因为之前对这个 index.js 文件从新建到删除,中间的所有 commit 合起来看是相互抵消的(因为文件最后被删除了,相当于没有新建过),所以单单输入 git log 指令,什么也看不到。即使代码被恢复后再输入 git log 指令,也只会展示恢复代码的那次 commit。

2.2.2. --stat 生成差异统计

git log 默认情况下不会生成文件差异:

加了 --stat 参数,即可生成文件差异的统计,执行以下命令:

git log --stat -- A/index.js

对比没加 –stat 参数的结果,可以看到多输出了文件的变更记录,具体到变更了多少文件、多少行代码。

2.2.3. --full-history

由 2.2.1 的介绍可知,git log 的默认模式是会简化文件历史的。为此,我们需要加上 --full-history 这个参数,去掉这个简化的功能。

执行以下命令:

git log --full-history -- A/index.js

对比 2.2.1,可以看到加了 --full-history 参数的输出结果没有进行简化,所有处理过该代码的 commit 都展示出来了。

2.2.4. --simplify-merges

--simplify-merges 可以增强 --full-history 的能力,因为 --full-history 会把一些无用的合并 commit 也输出出来(可以看 2.2.3 中的 commit 信息,有一些是 Merge branch xxx),增加 --simplify-merges 参数可以去除这些无用的 commit 信息。

执行以下命令:

git log --full-history --simplify-merges -- A/index.js

对比 2.2.3 中的输出结果,可以看到已经没有 Merge branch xxx 的 commit 了,这里展示的每个 commit 都是实实在在对指定文件进行了修改的。

再加上 --stat 参数输出文件的差异信息,最终可以得出我们前文使用到的查询指令:

git log --stat --full-history --simplify-merges -- <path>

3. 分析原因

3.1 为什么代码被删除了,CR 时却没有发现,仍能合到主干?

从上面的分析可以知道,代码是在 fix:1 这个 commit 中被删除的。而在工蜂(公司内类似 gitlab 的代码管理平台)中,根本就没有记录显示代码被删除。

我们使用 git show 命令来看下该 commit 的更改内容:

结果发现没有显示任何文件更改。

这就是 CR 时没有发现问题的原因了,因为删除代码的记录根本就没有出现在工蜂上,所以没人知道这些代码被删除了。

3.2 为什么工蜂和 git show 无法展示该 commit 的记录呢?

3.2.1 工蜂的结论

到底是不是因为这个原因呢?实践出真知,我们用一个例子去试一下:

在一个项目内,模拟两个分支在同时进行开发,在分支 A 新增了文件 new2.js,且修改 const.js。

新建 new2.js 如下:

修改 const.js 如下:

然后分支 B 再修改了 const.js:

分支 B 在 push 的时候,则需要处理一下冲突文件了。

此时我们关注到暂存区里的 new2.js:

如果在此时把 new2.js 从暂存区里剔除,冲突选择 Current Change ,再提交代码,就能成功复现工蜂不展示代码被删的问题了。

如果去 VSCode 上看,还是可以看到代码被删除的:

3.2.2 分析一下

合并后,项目的主干路径变为了红色的三个点,相当于 A 分支的两个修改都被 B 分支的 merge 操作覆盖掉了(新文件剔除出暂存区、冲突选择分支B部分)。最终 fix:fix1 节点相对于分支 B 的最新节点没有变化,故工蜂中 fix:fix1 节点显示没有文件变化。在分支 A 里新增的 new2.js 文件,相对于合并后的主干代码来说,就像从来没有出现过一样,所以在合并分支的节点中就不会有它被删除的记录。

回到丢失代码的项目里,打开 VSCode 的 git 管理模块查看该 commit:

能够看到是修改了很多文件的,其中就有删除 A 页面代码的记录,和我们例子的表现一致。

所以可以证明工蜂说的没错,应该是当时操作者在合并代码时,不知因为什么原因,把 A 页面代码剔除出了暂存区,最终导致 A 页面的代码像消失了一样。

4. 预防措施

目前发现代码被删除是被动的,也就是需要去找这些代码时,才能发现代码不见了,这也是代码被删了 8 个月才被发现的原因之一。

所以我们希望能够 化被动为主动 ,通过程序去帮助开发者提前发现这些问题,而不是在需要用到这些代码的时候,才发现代码已经没了,时间久了再排查、恢复都比较困难。

因此可以考虑实现一个 主干检查程序 ,将手动的处理方式改为使用代码逻辑去实现,然后每隔一段时间触发一次,检查有无类似的情况发生,能够做到出现类似情况发生后及时通知到开发者。

紧追技术前沿,深挖专业领域

扫码关注我们吧!

本文参与 腾讯云自媒体分享计划 ,分享自微信公众号。
原始发表:2021-12-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除
git
javascript

本文分享自 腾讯IMWeb前端团队 微信公众号, 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!

git
javascript
评论
登录 后参与评论
0 条评论
热度
最新
登录 后参与评论
关于作者
用户1097444
0
文章
0
累计阅读量
0
获赞
前往专栏
目录
  • 1. 问题背景
  • 2. 处理方式
    • 2.1 通过 git log 查找出修改过指定文件的 commit
      • 2.2. 解释一下命令及每个参数的作用
      • 3. 分析原因
        • 3.1 为什么代码被删除了,CR 时却没有发现,仍能合到主干?
          • 3.2 为什么工蜂和 git show 无法展示该 commit 的记录呢?
            • 3.2.1 工蜂的结论
            • 3.2.2 分析一下
        • 4. 预防措施
领券
  • 社区

    • 专栏文章
    • 阅读清单
    • 互动问答
    • 技术沙龙
    • 技术视频
    • 团队主页
    • 腾讯云TI平台
  • 活动

    • 自媒体分享计划
    • 邀请作者入驻
    • 自荐上首页
    • 技术竞赛
  • 资源

    • 技术周刊
    • 社区标签
    • 开发者手册
    • 开发者实验室
  • 关于

    • 社区规范
    • 免责声明
    • 联系我们
    • 友情链接

腾讯云开发者

扫码关注腾讯云开发者

扫码关注腾讯云开发者

领取腾讯云代金券

热门产品

  • 域名注册
  • 云服务器
  • 区块链服务
  • 消息队列
  • 网络加速
  • 云数据库
  • 域名解析
  • 云存储
  • 视频直播

热门推荐

  • 人脸识别
  • 腾讯会议
  • 企业云
  • CDN加速
  • 视频通话
  • 图像分析
  • MySQL 数据库
  • SSL 证书
  • 语音识别

更多推荐

  • 数据安全
  • 负载均衡
  • 短信
  • 文字识别
  • 云点播
  • 商标注册
  • 小程序开发
  • 网站监控
  • 数据迁移

Copyright © 2013 - 2023 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有

深圳市腾讯计算机系统有限公司 ICP备案/许可证号: 粤B2-20090059 深公网安备号 44030502008569

腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287

问题归档 专栏文章 快讯文章归档 关键词归档 开发者手册归档 开发者手册 Section 归档

Copyright © 2013 - 2023 Tencent Cloud.

All Rights Reserved. 腾讯云 版权所有

登录 后参与评论
 
推荐文章
机灵的莲藕  ·  DevOps - Git Internals: Architecture and Index Files | Microsoft Learn
4 周前
傻傻的甘蔗  ·  处理.git文件夹过大出现臃肿问题-filter-branch和BFG工具 - sowler
4 周前
文武双全的灭火器  ·  Git合并冲突处理指南:解决二进制文件冲突_git 二进制文件冲突
3 周前
踏实的碗  ·  浅谈HASH长度拓展攻击 - Yunen的博客 - 博客园
1 年前
伤情的莴苣  ·  react.js - fetch如何根据返回的http状态码输出返回json串中的错误信息 - SegmentFault 思否
1 年前
爱吹牛的大熊猫  ·  PyCharm远程调试代码 - 知乎
2 年前
挂过科的爆米花  ·  Python获取输入:sys.stdin与input()_python sys.stdin读第二行_一只干巴巴的海绵的博客-CSDN博客
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号