Git: Git日志查看与历史追溯

提交历史记录了项目的所有变更,是版本控制的核心价值。通过查看历史,可以了解项目的演进过程、追溯问题来源、分析开发轨迹。

1. 日志基础概念

(1) 什么是提交历史

提交历史是所有提交按照时间顺序排列的记录,包含:

100%
graph TB
    A[最新提交<br/>HEAD] --> B[提交C3<br/>a1b2c3d]
    B --> C[提交C2<br/>d4e5f6g]
    C --> D[提交C1<br/>h7i8j9k]
    D --> E[初始提交<br/>l0m1n2o]
    
    style A fill:#d4edda
    style E fill:#fff3cd

(2) 历史的作用

(3) Git日志命令

git log 是查看提交历史的主要命令,支持丰富的选项来定制输出。


2. 基本日志查看

(1) 查看完整历史

▶ 示例:查看提交历史

BASH
# 查看完整历史
git log

# 输出格式:
# commit a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0
# Author: 张三 <zhangsan@example.com>
# Date:   Mon Jan 1 10:00:00 2026 +0800
#
#     feat: 添加用户登录功能
#
# commit d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2
# Author: 李四 <lisi@example.com>
# Date:   Sun Dec 31 15:30:00 2025 +0800
#
#     fix: 修复登录验证错误

(2) 简洁模式

▶ 示例:简洁显示

BASH
# 一行显示一个提交
git log --oneline

# 输出:
# a1b2c3d feat: 添加用户登录功能
# d4e5f6g fix: 修复登录验证错误
# h7i8j9k docs: 更新README
# l0m1n2o Initial commit

# 简写形式
git log --oneline --decorate

# 输出:
# a1b2c3d (HEAD -> main) feat: 添加用户登录功能
# d4e5f6g (origin/main) fix: 修复登录验证错误

(3) 限制显示数量

▶ 示例:限制显示条数

BASH
# 显示最近3次提交
git log -3

# 或者
git log -n 3

# 简洁模式显示最近5次
git log --oneline -5

# 输出:
# a1b2c3d feat: 添加用户登录功能
# d4e5f6g fix: 修复登录验证错误
# h7i8j9k docs: 更新README
# k9l0m1n style: 格式化代码
# n2o3p4q refactor: 优化查询逻辑

3. 日志格式化输出

(1) 格式化选项

选项 说明 用途
--oneline 简洁模式 快速浏览历史
--stat 显示统计 查看文件变更统计
-p 显示差异 查看具体修改内容
--graph 图形显示 查看分支合并历史
--decorate 显示引用 查看分支和标签指向

▶ 示例:显示统计信息

BASH
# 显示文件变更统计
git log --stat

# 输出:
# commit a1b2c3d4e5f6...
# Author: 张三 <zhangsan@example.com>
# Date:   Mon Jan 1 10:00:00 2026 +0800
#
#     feat: 添加用户登录功能
#
#  src/auth/login.js | 25 +++++++++++++++++++++++++
#  src/auth/index.js  |  3 ++-
#  2 files changed, 26 insertions(+), 2 deletions(-)

(2) 显示完整差异

▶ 示例:查看提交差异

BASH
# 显示每次提交的完整差异
git log -p

# 显示最近一次提交的差异
git log -1 -p

# 输出:
# commit a1b2c3d4e5f6...
# Author: 张三 <zhangsan@example.com>
# Date:   Mon Jan 1 10:00:00 2026 +0800
#
#     feat: 添加用户登录功能
#
# diff --git a/src/auth/login.js b/src/auth/login.js
# new file mode 100644
# index 0000000..abc1234
# --- /dev/null
# +++ b/src/auth/login.js
# @@ -0,0 +1,25 @@
# +function login(username, password) {
# +  // 验证逻辑
# +}

(3) 自定义格式

▶ 示例:自定义输出格式

BASH
# 使用预设格式
git log --pretty=oneline
git log --pretty=short
git log --pretty=full
git log --pretty=fuller

# 自定义格式
git log --pretty=format:"%h - %an, %ar : %s"

# 输出:
# a1b2c3d - 张三, 2 hours ago : feat: 添加用户登录功能
# d4e5f6g - 李四, 1 day ago : fix: 修复登录验证错误

# 更详细的格式
git log --pretty=format:"%C(yellow)%h%C(reset) - %C(green)%an%C(reset), %C(blue)%ar%C(reset) : %s"

# 表格格式
git log --pretty=format:"%h | %an | %ad | %s" --date=short

# 输出:
# a1b2c3d | 张三 | 2026-01-01 | feat: 添加用户登录功能
# d4e5f6g | 李四 | 2025-12-31 | fix: 修复登录验证错误

(4) 格式占位符

占位符 说明 示例输出
%H 完整哈希 a1b2c3d4e5f6...
%h 短哈希 a1b2c3d
%an 作者名字 张三
%ae 作者邮箱 zhangsan@example.com
%ad 作者日期 Mon Jan 1 10:00:00 2026
%ar 作者日期(相对) 2 hours ago
%s 提交信息 feat: 添加功能
%d 引用名称 (HEAD -> main)

4. 日志过滤查询

(1) 按时间过滤

▶ 示例:时间范围过滤

BASH
# 指定日期之后
git log --since="2026-01-01"

# 指定日期之前
git log --until="2026-01-31"

# 相对时间
git log --since="1 week ago"
git log --since="2 months ago"
git log --after="yesterday"

# 时间范围
git log --since="2026-01-01" --until="2026-01-31"

# 组合使用
git log --oneline --since="1 week ago" --until="yesterday"

(2) 按作者过滤

▶ 示例:作者过滤

BASH
# 按作者名字
git log --author="张三"

# 按作者邮箱
git log --author="zhangsan@example.com"

# 模糊匹配
git log --author="张"

# 组合过滤
git log --author="张三" --since="1 week ago"

(3) 按提交信息过滤

▶ 示例:提交信息搜索

BASH
# 搜索提交信息
git log --grep="fix"

# 多个条件(或关系)
git log --grep="fix" --grep="feat"

# 正则表达式
git log --grep="feat\|fix"

# 忽略大小写
git log --grep="FIX" -i

# 组合过滤
git log --author="张三" --grep="feat"

(4) 按文件过滤

▶ 示例:文件历史查询

BASH
# 查看特定文件的历史
git log -- README.md

# 查看多个文件
git log -- file1.js file2.js

# 查看目录历史
git log -- src/auth/

# 显示文件差异
git log -p -- README.md

# 显示文件变更统计
git log --stat -- README.md

# 只显示修改该文件的提交
git log --oneline -- README.md

# 输出:
# a1b2c3d docs: 更新README
# h7i8j9k docs: 添加安装说明
# l0m1n2o Initial commit

(5) 按提交范围过滤

▶ 示例:提交范围查询

BASH
# 查看两个提交之间的历史
git log a1b2c3d..d4e5f6g

# 查看某个提交之后的历史
git log a1b2c3d..

# 查看某个提交之前的历史
git log ..d4e5f6g

# 查看分支差异
git log main..feature

# 查看两个分支的差异
git log main...feature

5. 图形化显示

(1) 显示分支图

▶ 示例:图形化日志

BASH
# 显示分支合并图
git log --graph

# 常用组合
git log --graph --oneline --all

# 输出:
# *   a1b2c3d Merge branch 'feature'
# |\
# | * d4e5f6g Add feature
# * | b7c8d9e Fix bug
# |/
# * c0d1e2f Initial commit

# 带装饰信息
git log --graph --oneline --decorate --all

# 彩色输出
git log --graph --oneline --all --pretty=format:"%C(red)%h%C(reset) - %C(green)%s%C(reset)"

(2) 分支历史可视化

100%
gitGraph
    commit id: "Initial commit"
    commit id: "Add feature A"
    branch feature
    checkout feature
    commit id: "Feature work"
    checkout main
    commit id: "Fix bug"
    merge feature id: "Merge feature"
    commit id: "Release v1.0"

(3) 查看分支演进

▶ 示例:分支演进历史

BASH
# 查看所有分支历史
git log --graph --oneline --all --decorate

# 查看特定分支历史
git log --graph --oneline feature

# 查看分支分叉点
git log --graph --oneline --simplify-by-decoration

# 查看合并提交
git log --merges --oneline

# 查看非合并提交
git log --no-merges --oneline

6. 高级日志技巧

(1) 二分查找

使用 git bisect 定位引入问题的提交:

▶ 示例:二分查找问题提交

BASH
# 开始二分查找
git bisect start

# 标记当前提交为有问题
git bisect bad

# 标记某个提交为正常
git bisect good v1.0.0

# Git会自动切换到中间提交
# 测试后标记为good或bad
git bisect good
# 或
git bisect bad

# 找到问题提交后
# a1b2c3d is the first bad commit

# 结束二分查找
git bisect reset

(2) 查看文件变更历史

▶ 示例:文件历史分析

BASH
# 查看文件的完整变更历史
git log --follow -p -- filename

# 查看文件每一行的修改历史
git blame filename

# 输出:
# a1b2c3d (张三 2026-01-01 10:00:00  1) function login() {
# d4e5f6g (李四 2025-12-31 15:30:00  2)   // 验证逻辑
# h7i8j9k (张三 2025-12-30 09:00:00  3) }

# 查看特定行的历史
git log -L 10,20:filename

# 查看函数历史
git log -L :functionName:filename

(3) 引用日志

▶ 示例:查看引用日志

BASH
# 查看HEAD的移动历史
git reflog

# 输出:
# a1b2c3d HEAD@{0}: commit: feat: 添加功能
# d4e5f6g HEAD@{1}: checkout: moving from feature to main
# h7i8j9k HEAD@{2}: commit: Feature work
# l0m1n2o HEAD@{3}: checkout: moving from main to feature

# 查看特定引用的历史
git reflog show HEAD
git reflog show main

# 恢复到之前的状态
git reset HEAD@{5}

❓ 常见问题

Q 如何查看某个文件的修改历史?
A 使用 git log -- <文件名> 查看文件的提交历史,使用 git log -p -- <文件名> 查看详细的修改内容,使用 git blame <文件名> 查看每一行的修改记录。
Q 如何查看两次提交之间的差异?
A 使用 git log <提交1>..<提交2> 查看两次提交之间的历史,使用 git diff <提交1> <提交2> 查看具体的文件差异。
Q 如何找到引入某个Bug的提交?
A 使用 git bisect 进行二分查找。标记一个已知正常的提交和一个已知有问题的提交,Git会自动定位引入问题的提交。
Q log和reflog有什么区别?
A git log 显示提交历史,是项目演进的记录;git reflog 显示引用的移动历史,包括提交、重置、检出等所有操作,即使提交被丢弃也能在reflog中找到。
Q 如何查看已删除文件的历史?
A 使用 git log --all --full-history -- <文件名> 可以查看已删除文件的完整历史,包括删除操作。

📖 小节


📝 作业

  1. 基础题:使用 git log 的各种选项查看项目历史,包括简洁模式、统计信息、图形化显示,并尝试自定义输出格式。

  2. 进阶题:使用过滤选项查找特定条件的提交,例如:查找最近一周的提交、查找某个作者的所有提交、查找提交信息包含"fix"的提交。

  3. 挑战题:使用 git bisect 在一个包含多个提交的项目中定位引入某个问题的提交,体验二分查找的强大功能。

Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏