调试与搜索
本教程共 26 篇 · 第 25 篇 · 更新于 2026-07-29 · 约 6 分钟阅读
25. 调试与搜索
本节目标:学会用 blame 找”谁改的这行代码”,用 bisect 定位”哪个提交引入的 bug”,用 grep 快速搜索代码。
git blame:逐行追溯
git blame 能告诉你文件中每一行最后一次是谁、在哪个提交里改的。
基本用法
git blame README.md
输出:
a1b2c3d4 (张三 2026-07-01 10:30:00 +0800 1) # 项目介绍
e4f5g6h7 (李四 2026-07-15 14:20:00 +0800 2) 这是一个示例项目
i7j8k9l0 (张三 2026-07-20 09:15:00 +0800 3) 用于演示 git blame
每行前面是提交哈希、作者、日期和时间,最后是行号。
只看指定行范围
git blame -L 10,20 README.md
只看第 10 到第 20 行。
显示邮箱
git blame -e README.md
会显示作者的邮箱而不是名字。
忽略空白改动
git blame -w README.md
忽略空格、缩进的变化,只看实质内容改动。
Note
blame这个名字听起来像在”指责”人。但它的本意是追溯代码来源,不是甩锅工具。用的时候注意语气——“这行代码的上下文是什么”比”谁写的 bug”有用多了。
git bisect:二分排查
当你知道某个 bug 存在,但不确定是哪个提交引入的,git bisect 能帮你快速定位。
它的原理是二分查找:在”好的提交”和”坏的提交”之间反复折半,每次测试中间那个提交,直到找到第一个引入 bug 的提交。
手动模式
- 启动 bisect:
git bisect start
- 标记当前版本是有 bug 的:
git bisect bad
- 标记一个已知没问题的版本:
git bisect good v1.0
Git 会自动检出中间那个提交。你测试一下,告诉 Git 这个版本是好是坏:
# 如果这个版本没问题
git bisect good
# 如果这个版本有 bug
git bisect bad
Git 继续折半。重复这个过程,直到找到第一个坏提交:
b047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commit
commit b047b02ea83310a70fd603dc8cd7a6cd13d15c04
Author: 张三 <zhangsan@example.com>
Date: Tue Jul 15 14:48:32 2026 +08:00
添加新功能 X
- 完成后重置状态:
git bisect reset
自动模式
如果你有个脚本能自动判断好坏(返回 0 表示好,非 0 表示坏),可以让 bisect 全自动跑:
git bisect start HEAD v1.0
git bisect run ./test.sh
test.sh 是你的测试脚本。Git 会自动在每个提交上跑这个脚本,直到找到第一个坏提交。
Note自动模式要求你的测试脚本能独立运行,不依赖外部服务。如果测试需要联网或连数据库,手动模式更靠谱。
跳过无法测试的提交
有些提交可能编译不过,没法测试。可以跳过:
git bisect skip
git grep:代码搜索
git grep 能在仓库中搜索字符串或正则表达式。比系统自带的 grep 更快,因为直接搜 Git 索引。
基本搜索
git grep "TODO"
搜索工作目录中所有包含 “TODO” 的文件。
显示行号
git grep -n "TODO"
src/main.py:42: # TODO: 优化性能
src/utils.py:15: # TODO: 添加错误处理
只显示文件名
git grep -l "TODO"
统计匹配数量
git grep --count "TODO"
src/main.py:3
src/utils.py:1
搜索指定文件类型
git grep "TODO" -- '*.py'
只在 Python 文件中搜索。
显示上下文
git grep -p "TODO" '*.py'
显示匹配行所在的函数或方法名,方便理解上下文。
组合条件搜索
git grep -e "MAX" --and -e "BUFFER" -- '*.c'
搜索同时包含 “MAX” 和 “BUFFER” 的行。
搜索历史提交
git grep 默认只搜工作目录。想搜历史提交,用 git log -S 或 git log -G:
git log -S "someFunction" --oneline
找出所有增加或删除了 “someFunction” 字符串的提交。
git log -G "someFunction\(" --oneline
用正则表达式搜索 diff 内容。
三个命令的配合使用
实际调试中,这三个命令经常配合使用:
- 用
git grep找到可疑的代码位置 - 用
git blame看这行代码是谁、什么时候改的 - 用
git bisect精确定位引入 bug 的提交
比如你发现 config.py 里有个值不对:
# 1. 找到这个值在哪
git grep "MAX_CONNECTIONS" -- '*.py'
# 2. 看这行是谁改的
git blame config.py -L 10,15
# 3. 如果改动很多,用 bisect 定位
git bisect start
git bisect bad
git bisect good v1.0
# ... 反复测试
对比系统 grep
| 对比项 | git grep | grep |
|---|---|---|
| 速度 | 快(搜 Git 索引) | 慢(遍历文件) |
| 忽略 .gitignore | 自动 | 需要手动排除 |
| 搜索历史 | 不支持(用 log -S) | 不支持 |
| 跨分支搜索 | 可以指定树 | 只能搜当前目录 |
一句话总结:blame 找责任人,bisect 找元凶,grep 找位置。三个命令组合起来,没有查不出的 bug。
这章学到了什么
git blame逐行追溯代码来源,告诉你每行是谁、什么时候改的git bisect二分排查 bug 引入点,支持手动模式和自动模式(bisect run)git grep快速搜索代码内容,比系统 grep 更快,自动忽略 .gitignore- 三个命令配合使用:grep 找位置,blame 看谁改的,bisect 定位引入点
git log -S和git log -G可以搜索历史提交中的内容变化
这是本教程的最后一章正式内容。下一章,我们来总览三种主流 Git 工作流。