功能明明「以前有」,现在代码里找不到——用 git pickaxe 反查被静默删除的历史
用户反馈:"搜索历史记录这个功能以前有的,现在怎么没了?"
我第一反应是直接 grep 关键词——结果全仓库 0 命中。git log --grep "搜索历史" 也只有一条不相关的 PR 描述。难道是用户记错了?仔细一想不对:如果从来没有过,CSS 文件里不会留着 .search-history-item 和 .search-section-clear 这几个孤立的 class。
这是典型的「半删」——功能被顺手埋进某次 UI 整理 commit,commit message 完全没提,但后端 API 和样式没来得及清理干净。
现象
- 当前代码 grep 功能关键字段(方法名、storage key、文案):0 命中
git log --grep "关键词"搜 commit message:0 命中- 但能看到「半身残留」:CSS 里还有对应的 class,后端 API 定义文件里还有接口声明
这三条加在一起就可以确认:功能曾经存在,且被不完整地删掉了。
根因
git log --grep 只搜索 commit message 文本,而功能删除往往发生在泛化描述的 UI 整理类 commit 里,比如 fix(ui): refine scrolling and page interactions——作者自己可能都没意识到顺手删掉了一整块 feature。
「删了搜索历史功能」的那个 commit,它的 message 是 fix(ui): refine scrolling and page interactions。你永远不可能用 git log --grep "搜索历史" 找到它。
更糟的是,如果此时选择「凭经验重新实现」,字段名、方法签名、后端接口约定必然发生漂移,埋下未来的兼容 bug——而后端其实根本没动,接口还活着。
正解
第一步:用 pickaxe 精确定位「把功能删掉的 commit」
git log -S 是 git 的 pickaxe 模式,它不搜 message,而是搜 diff 内容:只列出某个字符串在 diff 中「出现过或消失过」的 commit。
# 全仓库搜,找到哪个 commit 改动了包含该符号的文件
git log --all --oneline -S "searchHistory"
# 限定目录,加速搜索
git log --all --oneline -S "searchHistory" -- pages/home/
# 直接看 diff,确认是哪次 commit 删的(- 侧是被删内容)
git log --all -p -S "addSearchHistory" -- pages/home/maps.js关键字选择原则:选最独特的符号(storage key、自定义方法名、独特 API path),避免 search、history 这类太泛的词误伤大量不相关 commit。
命中最新的那个 commit 通常就是「删除方」,用 git show <sha> --stat 验证改了哪些文件,用 git show <sha> -- <path> 看具体 diff 的 - 侧确认。
第二步:三路交叉验证「曾经存在 + 未彻底下线」
找到 commit 之后,再横向确认残留情况:
| 层 | 检查命令 | 意义 |
|---|---|---|
| 后端 API | grep -n "<endpoint>" <api-client-file> | 接口还在 → 直接复用,无需重写后端 |
| CSS/WXSS | grep -n "\.<class>" <css-file> | 样式还在 → 恢复 WXML 后立即生效 |
| i18n/文案 | grep -n "<text>" <locale-file> | 文案还在 → 产品未明确下线 |
三路都有残留 = 确认「半删」,可安全恢复;若后端/DB 已清理 = 重建工作量大,先和产品重新对齐需求。
第三步:从历史快照拉「删除前源码」
不要凭记忆重写,直接从删除前的父提交拉快照:
# <sha>^ 表示该 commit 的父提交,即删除前的最后一个版本
git show <sha>^:pages/home/maps.js > /tmp/maps_before.js
git show <sha>^:pages/home/maps.wxml > /tmp/maps_before.wxml拿到快照后,以它为唯一事实源做恢复:
- 原样抄函数体,不重构、不简化、不加 log
- 字段命名、调用签名、data flow 一字不改
- 如有新增需求(如「有缓存时优先缓存,无缓存时展示历史」),在复原基础上增量追加,不要和复原逻辑混写成「重新设计」
git log -S "<最独特符号>"找到删除方 commit(10 分钟内命中)- API / CSS / i18n 三路验证残留层,判断恢复工作量
git show <sha>^:<path>拉删除前快照作为唯一实现参考- 原样复原 + 增量追加,杜绝签名漂移
本次排查顺手发现:后端 API 定义文件里留了 4 个「死接口」声明,CSS 里留了 5 个「死 class」——这些是上次不彻底删除留下的技术债。如果不顺手记录,下次再有人误删会重复踩同一个坑。
一句话外卖
git log --grep搜 message,git log -S搜内容——功能被静默删除时,只有 pickaxe 能找到真正的祸首 commit。