Command Reference

git log 教程

说明 git log 如何查看提交历史、分支图结构、作者和范围过滤,并把它真正用到评审、同步和恢复判断中。

适合谁看
  • 已经会基本提交和分支操作的开发者
  • 想理解命令边界与风险的人
前置知识
  • 知道工作区、暂存区、提交的基本关系
  • 能读懂 `git status` 和简单历史图
常见风险
  • 误把本地整理命令用到共享历史
  • 在没确认恢复路径前直接继续改写历史

一句话理解

git log 是阅读历史的核心命令,它不只是看提交列表,更重要的是帮助你理解分支关系、共同祖先和当前历史到底长成了什么样。

log 不只是看过去,而是为下一步决策提供依据

git log 的价值常常不在“读到了什么”,而在它帮助你避免了哪一个错误的 merge、rebase、reset 或恢复动作。

日常最有价值的写法

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

这条命令很值得形成肌肉记忆,因为它同时给你:

  • 短提交 ID
  • 分支图结构
  • tag 和分支标签
  • 所有 refs 的上下文

很多排障和 review 场景,第一眼看它就够了。

它能帮你回答哪些问题

例如:

  • 这个分支最近到底做了什么?
  • 我的分支和 main 从哪里分叉?
  • 某个提交是不是已经进了另一个分支?
  • 事故发生前最后一个稳定点在哪里?
  • 为什么现在仓库历史会长成这样?

所以 git log 既是日常命令,也是恢复和分析命令。

几种实用形式

看最近几条提交

git log -5 --oneline

按作者过滤

git log --author="Alice"

看某个文件的历史

git log -- path/to/file

看当前功能分支比 main 多了什么

git log main..feature/login --oneline

它适合回答:"我这个分支有哪些提交是 main 还没有的?"

进阶用法

自定义输出格式

--format 参数允许你完全自定义 log 输出:

git log --format="%h %an %ar %s"

常用占位符:

占位符说明示例输出
%h短提交哈希a1b2c3d
%H完整提交哈希a1b2c3d4e5f6...
%an作者姓名张三
%ae作者邮箱zhang@example.com
%cn提交者姓名李四
%ad作者日期(尊重 --date 格式)2024-03-15
%ar作者日期(相对时间)3 days ago
%s提交标题feat: add login page
%b提交正文完整的 commit message body
%D引用名称(分支、标签)HEAD -> main, tag: v1.0

预设格式也值得一记:

git log --format=oneline    # 一行一条
git log --format=short      # 简要信息
git log --format=full       # 完整信息
git log --format=fuller     # 最详细,含作者和提交者
git log --format=email      # 兼容 email patch 格式

搜索历史

选项说明示例
-S<string>查找增减该字符串的提交git log -S"password"
-G<regex>查找匹配正则的提交git log -G"TODO.*fix"
--grep=<pattern>在提交信息中搜索git log --grep="bug fix"
--author=<pattern>按作者过滤git log --author="Alice"
--committer=<pattern>按提交者过滤git log --committer="Bob"

-S-G 的区别很重要:-S 追踪字符串出现次数的变化("pickaxe"搜索),适合找某个代码是什么时候引入或删除的;-G 则匹配 diff 内容中的正则。

文件追踪与重命名

git log --follow -- path/to/file

--follow 会让 log 跨越文件重命名继续追踪历史。默认情况下,如果文件被重命名,git log -- path/to/newname 只会显示重命名后的历史,加上 --follow 才能看到完整的追踪链条。

统计变更

选项说明
--stat每个文件变更行数的柱状图
--shortstat只显示汇总:几个文件变、几行增、几行删
--numstat纯数字格式,方便脚本处理
# 查看最近 10 条提交的汇总统计
git log -10 --shortstat

# 统计某个作者的全部变更量
git log --author="Alice" --shortstat --oneline

时间范围过滤

# 最近两周的提交
git log --since="2 weeks ago"

# 特定日期范围
git log --after="2024-01-01" --before="2024-03-01"

# 也可以使用 --since / --until
git log --since="2024-01-01" --until="2024-02-01"

# 组合使用:某个作者的最近提交
git log --author="Alice" --since="3 months ago" --oneline

--since--after 等价,--until--before 等价。时间格式非常灵活,支持相对时间(2 weeks ago)和绝对时间(2024-01-01)。

图形输出变体

# 带颜色的分支图
git log --oneline --graph --decorate --all --color

# 限制层级深度的图
git log --oneline --graph -20

# 每个提交一行,带颜色和引用
git log --oneline --graph --all --decorate --color --format="%C(yellow)%h%C(reset) %C(cyan)%an%C(reset) %s %C(green)(%ar)%C(reset)"

--graph 绘制 ASCII 分支图,--decorate 显示引用名称,--all 展示所有分支。加上颜色代码(%C(yellow) 等)可以让输出更易读。

在高风险动作前怎么用它

在做 rebase、reset、revert 或恢复前,很推荐这样做:

  1. git status
  2. git log --oneline --graph --decorate --all -20
  3. 找到可能需要回退或参考的那个点
  4. 再执行真正会改历史的动作

这样能显著降低“在模糊印象上操作历史”的风险。

图例理解

观察历史,获得决策依据观察类命令通常不直接改写历史,但它们决定了你后续的历史操作是不是基于证据。
观察对象
提交历史引用分支头路径历史
产出
可见的祖先关系评审上下文恢复目标
很多时候,`git log` 最大的价值不是输出本身,而是阻止了错误的下一步。

常见误解

  • git log 不是脱离范围的“真相”,它只能展示你指定范围内的历史。
  • 只看线性列表很容易忽略分支结构,所以 --graph --decorate --all 很重要。
  • 文件历史和分支历史回答的是不同问题,不能互相替代。
先上 graph,再上高级过滤

当仓库历史看起来很乱时,先加 --graph --decorate --all,通常比一开始就堆很多过滤参数更有效。

边界与配套命令

git log 最适合和这些命令配合使用:

  • git show:看单个提交的详细内容
  • git diff:看精确差异
  • git reflog:看本地分支指针如何移动过

如果 git log 看起来怪,下一步通常不是怀疑 Git,而是确认自己看的范围对不对。

不要把 log 和 reflog 混为一谈

git log 展示的是提交祖先关系,git reflog 记录的是本地 ref 如何移动。它们都重要,但不是在回答同一个问题。

跟着做一遍

练习:在整合前先看懂分支分叉

目标是把 `git log` 从“看历史”变成“做决定前的检查工具”。

准备
git switch -c lab/log-demo
# 在分支上做两次提交
# 再让 main 前进一次
动手试
  1. 运行 `git log --oneline --graph --decorate --all -12`。
  2. 运行 `git log main..HEAD --oneline` 看当前分支独有提交。
  3. 运行 `git log HEAD..main --oneline` 看上游比你多了什么。
  4. 再判断下一步更适合 merge、rebase 还是暂时不动。
会发生什么
  • 你会看到分叉关系,而不是靠猜。
  • 你能判断当前分支是 ahead、behind 还是 both。
  • 后续整合决策会更有证据。
常见错误判断
  • 如果图太简单,记得加 `--all` 和 `--decorate`。
  • 如果输出为空,先确认 refs 是否写对。
  • 如果你需要的是本地恢复轨迹,应该转向 `git reflog`。