历史追踪与代码考古

这一类命令用于回答“什么时候改的、谁改的、为什么改”。排查回归、理解旧设计、定位责任提交时很常用。

git log main

git log main

用途:查看某个分支的提交历史。

适用场景:

  • 看 main 分支最近有哪些提交。
  • 确认某个功能是否已经进入目标分支。

常见增强:

git log --oneline main
git log --graph main
git log --oneline --graph --decorate --all

说明:

  • --oneline 每个提交显示一行,适合快速浏览。
  • --graph 用 ASCII 图展示分支和合并关系。
  • --decorate 显示分支名、tag 等引用。

git log -- <file>

git log -- README.md

用途:查看修改过某个文件的提交历史。

适用场景:

  • 想知道某个文件最近由哪些提交改过。
  • 排查某个文件的行为变化来源。

常用组合:

git log --oneline -- README.md
git log -p -- README.md

-p 会显示每个提交的具体 patch,适合深入追踪。

git log --follow <file>

git log --follow -- README.md

用途:查看某个文件的历史,并尽量跨越重命名继续追踪。

适用场景:

  • 文件被移动或重命名过,普通 git log -- <file> 看不到更早历史。

注意:

  • --follow 对复杂拆分、合并或大规模重构不一定完美,需要结合 git show 和路径历史判断。

git log -G <text>

git log -G banana

用途:查找哪些提交增加或删除过匹配文本的代码行。

适用场景:

  • 找某个函数调用、配置项、错误消息第一次出现或被删除的位置。
  • 排查某段逻辑什么时候被改过。

示例:

git log -G "memory_gate"
git log -G "legacy_flag" -- src/

说明:

  • -G 后面是正则表达式。
  • 如果只想查提交消息,可以用 git log --grep <text>,两者含义不同。

git blame <file>

git blame -- README.md

用途:显示文件每一行最后由哪个提交、作者和时间修改。

适用场景:

  • 找一行代码或配置的引入提交。
  • 需要进一步看该提交的上下文。

推荐组合:

git blame -- README.md
git show HEAD~1

注意:

  • blame 显示的是最后修改该行的人,不一定是问题的根因。
  • 格式化、重排或大规模迁移可能会污染 blame 结果,需要结合历史上下文判断。

恢复旧版本文件

git restore --source=HEAD~1 -- README.md

旧写法:

git checkout HEAD~1 -- README.md

用途:从某个旧提交取回指定文件版本,放到当前工作区。

适用场景:

  • 某个文件新版有问题,想临时拿回旧版本对比或恢复。
  • 只恢复一个文件,而不是整个仓库回退。

注意:这会修改当前工作区的该文件,确认后还需要 git add 和 git commit 才会进入历史。

代码考古练习

在隔离项目中选择一句确定存在的文本,先用 git log -G "长度" --all -- prompts/summary.md 找候选提交,再用 git show 核对 patch,最后用 git blame -- prompts/summary.md 判断当前行最后一次由哪个提交修改。把“候选证据”和“最终结论”分开记录,避免把最后修改者直接当作问题根因。