Skip to content

追溯与审计

Git 提供了强大的追溯工具,帮助你了解代码的历史变迁:哪行代码是谁写的、什么时候写的、为什么这样写。

git blame 查看每行的最后修改

git blame 显示文件中每一行最后一次被修改的提交信息和作者:

bash
# 基本用法
git blame src/app.js

# 输出格式:
# abc123ab (Zhang San 2026-03-01 10:30:00 +0800  1) import React from 'react';
# def456de (Li Si    2026-02-15 14:20:00 +0800  2)
# ghi789gh (Zhang San 2026-03-05 09:15:00 +0800  3) function App() {
# ...

输出字段说明:

  • abc123ab:缩短的提交 SHA-1
  • Zhang San:作者名
  • 2026-03-01 10:30:00 +0800:修改时间
  • 1:行号
  • import React from 'react';:行内容

git blame -L 指定行范围

bash
# 只查看第 10-20 行
git blame -L 10,20 src/app.js

# 查看第 10 行开始的 5 行
git blame -L 10,+5 src/app.js

# 查看从第 10 行到末尾
git blame -L 10, src/app.js

# 查看包含某个函数的行范围(按函数名)
git blame -L '/function login/','/^}/' src/auth.js

git blame -w 忽略空白改动

忽略空白字符(缩进调整、行尾空格等)的修改,找到内容实际修改的提交:

bash
# 忽略空白改动
git blame -w src/app.js

# 忽略空白 + 只查看特定行范围
git blame -w -L 10,20 src/app.js

git blame 其他选项

bash
# 显示完整的 SHA-1
git blame --show-stats src/app.js

# 以电子邮件显示作者
git blame -e src/app.js

# 查看特定提交时该文件的状态(时光机)
git blame abc123 -- src/app.js

# 忽略提交列表中的改动(如格式化提交)
git blame --ignore-rev abc123 src/app.js
git blame --ignore-revs-file .git-blame-ignore-revs src/app.js

配置忽略格式化提交:

bash
# 创建 .git-blame-ignore-revs 文件
cat > .git-blame-ignore-revs << 'EOF'
# Ignore formatting commits
abc123456789   # feat: 格式化代码
def456789012   # chore: 统一代码风格
EOF

# 配置 Git 使用此文件
git config blame.ignoreRevsFile .git-blame-ignore-revs

git log -p -L 追踪函数的变更历史

查看一个函数随时间的演变(比 blame 更强大):

bash
# 追踪函数 login 在 src/auth.js 中的变更历史
git log -p -L '/function login/','/^}/' src/auth.js

# 追踪特定行范围的变更历史
git log -p -L 10,25:src/auth.js

# 输出:每个改变了这些行的提交及其 diff

git log --follow 跟踪重命名

普通的 git log 在文件重命名后会停止追踪。--follow 能跨重命名追踪:

bash
# 追踪文件完整历史(包括重命名前)
git log --follow --oneline src/auth/login.js
# 即使文件曾经叫 src/login.js,也能看到完整历史

# 配合 -p 查看所有改动
git log --follow -p src/auth/login.js

代码考古实践

找到某行代码是何时引入的

bash
# 1. 用 blame 找到最后修改的提交
git blame -L 42,42 src/app.js
# abc123 (Zhang San 2026-02-01 ...) 42)   return undefined;  ← 可疑行

# 2. 查看那次提交的完整改动
git show abc123

# 3. 了解上下文:这个提交解决了什么问题
git show abc123 --stat

追踪 bug 的引入

bash
# 使用 pickaxe 找到某字符串最早出现/消失的提交
git log -S "offending_code" --oneline

# 查看该提交引入了什么
git show <sha>

# 结合 blame 了解完整上下文
git blame -L <line>,<line> <file>

理解某段代码的历史

bash
# 完整追踪 src/api.js 的 50-80 行代码历史
git log --topo-order --graph -p -L 50,80:src/api.js

# 按修改次数排序所有文件(找出热点文件)
git log --name-only --pretty=format: | sort | uniq -c | sort -rn | head -20

实用审计场景

谁引入了这个 bug?

bash
# 1. 确定 bug 所在行
git blame src/payment.js | grep "invalid_calculation"
# abc123 (Dev A 2026-01-15)  return amount * (1 + tax);  ← 发现问题

# 2. 查看提交详情
git show abc123

# 3. 了解 PR 背景(如果有 PR 信息)
git log abc123 --format="%s%n%b"

统计代码贡献

bash
# 统计每个人对仓库的贡献行数(粗略)
git ls-files | xargs -n1 git blame --line-porcelain | \
  grep "^author " | sort | uniq -c | sort -rn

# 用 git shortlog 统计提交数
git shortlog -sn --no-merges

总结

操作命令
查看文件每行责任人git blame <file>
查看指定行范围git blame -L <start>,<end> <file>
忽略空白改动git blame -w <file>
追踪函数变更历史git log -p -L '/func/','/}/' <file>
跟踪重命名文件git log --follow <file>
按内容搜索提交git log -S "<string>"

这些审计工具配合使用,能帮助你还原代码演变的完整故事,无论是 code review、bug 追踪还是了解设计决策,都非常有价值。