☰
til 仓库 Git 技巧:用 git log -p 在提交历史中直接查看文件 Diff
2026/10/5 6:42:29 网站建设 项目流程
  • 文档
  • 教程
  • 知识库

【免费下载链接】til

:memo: Today I Learned

项目地址:https://gitcode.com/gh_mirrors/ti/til
点击查看免费下载

在日常代码审查与历史追溯中,我们经常需要同时确认"这次提交改了什么"与"具体是怎么改的"。默认的git log只展示提交元信息(作者、时间、提交说明),而git log -p可以在浏览提交历史的同时,把每个提交对应的文件 Diff 一并展示出来,无需再逐个执行git show。本文以本仓库(til,Today I Learned 系列笔记仓库)为实例,完整讲解git log -p的用法、输出结构,并结合仓库中积累的 Git 技巧笔记,介绍--stat、路径过滤、范围语法、分页器与外部 Diff 工具等配套玩法,帮助你把这一个命令用好、用透。

git log -p基础用法:提交历史与 Diff 同屏展示

在 show-file-diffs-when-viewing-git-log.md 中记录的核心技巧非常简洁:为git log命令加上-p标志,即可把每个提交的 Diff 与其余信息一并输出。

$ git log -p

在本仓库中运行这条命令,会得到类似下面的输出(截取自仓库历史中的一个提交):

$ git log -p commit b9809a329acd8150b2474168f8faaf008f376e35 Author: jbranchaud <jbranchaud@gmail.com> Date: Wed Oct 11 07:27:53 2017 -0500 Add Inline Style Attributes Should Be Camel Cased as a react til diff --git a/README.md b/README.md index c982f8e..6ee7d32 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ smart people at [Hashrocket](http://hashrocket.com/). For a steady stream of TILs from a variety of rocketeers, checkout [til.hashrocket.com](https://til.hashrocket.com/). -_574 TILs and counting..._ +_575 TILs and counting..._ ---

输出结构逐段解读

git log -p的输出实际上是"若干段提交信息 + 若干段 diff"的交替组合,每段提交对应一组 diff:

  1. 提交头(commit header):完整 SHA、作者、时间戳、提交说明。命令默认按时间倒序排列,最新的提交在最前面。
  2. diff 文件头:diff --git a/README.md b/README.md标明变更的文件;index c982f8e..6ee7d32 100644给出文件在两个版本中的 blob 哈希与文件模式。
  3. ---与+++行:分别对应旧文件(a/)与新文件(b/)。
  4. hunk 头:@@ -10,7 +10,7 @@表示旧文件第 10 行起共 7 行、新文件第 10 行起共 7 行,后随上下文片段。
  5. 变更内容:-前缀为删除行,+前缀为新增行,无前缀为上下文行。

以上例来说,这是一个标准的"计数递增"提交:作者新增一篇 react 主题的 TIL 笔记,同时把 README 中的_574 TILs and counting..._更新为_575 TILs and counting..._。这种"新增文件 + 更新计数"的提交模式在 til 仓库中十分常见,用git log -p一条命令就能完整复盘整个改动过程。

等价形式与注意事项

  • -p与--patch等价,git log --patch写法同样合法,-p只是简写。
  • git log -p输出的完整字段(diff 头、index 行、hunk 头等)与git diff保持一致,因为两者底层复用同一套 diff 渲染逻辑。
  • 当提交涉及多个文件时,每个文件会依次输出一段独立的diff --git ...块。
  • 若某提交是一次 merge(合并提交),git log -p默认不展开合并差异,需配合-m或--first-parent等参数处理,可查阅man git-log了解详情。

用--stat先看统计,再决定要不要看全文

git log -p的信息量最大,但也最容易刷屏。如果想先快速掌握"每个提交动了哪些文件、增删了多少行",可以改用--stat标志,只输出每个提交的 diffstat 统计摘要,而不输出具体 diff 内容。这一点在 include-some-stats-in-your-git-log.md 中有完整示例:

$ git log --stat commit 66e67741a1cd6857a4467d1453c9f17ef5849f20 Author: jbranchaud <jbranchaud@gmail.com> Date: Mon Nov 13 21:24:41 2017 -0600 Add Focus The URL Bar as an internet til README.md | 3 ++- internet/focus-the-url-bar.md | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) commit 9241e3919ef1e4f68b71a1491d368ae6361084aa Author: jbranchaud <jbranchaud@gmail.com> Date: Sat Nov 11 11:41:40 2017 -0600 Add Freeze An Object, Sorta as a javascript til README.md | 3 ++- javascript/freeze-an-object-sorta.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) ...

每个文件后的竖线柱状图直观展示相对改动量,末尾的2 files changed, 12 insertions(+), 1 deletion(-)是汇总。这与git log -p是互补的两档输出粒度:先用--stat扫一遍改动规模,再用-p聚焦细看。

类似的,show-the-diffstat-summary-of-a-commit.md 记录了对单个提交执行git show <sha> --stat的用法:

$ git show 8a1f36a1ce --stat commit 8a1f36a1ce71d708d1d82afbc2191de9aefba021 Author: Derek Parker <derek.parker@coreos.com> Date: Wed Jan 27 23:47:04 2016 -0800 dlv: Flag to print stacktrace on trace subcommand cmd/dlv/main.go | 45 ++++++++++----------------------------------- terminal/command.go | 7 +++++-- 2 files changed, 15 insertions(+), 37 deletions(-)

diffstat 工具的本质是"读取 diff 输出,按文件绘制插入、删除、修改的直方图"——git log --stat、git show --stat都是 Git 内置的 diffstat 呈现方式。如需更细的字段控制,git log --stat还支持--stat-width、--stat-name-width等参数调整列宽。

只要文件名、不要 diff:--name-only与--name-status

如果只关心"这个提交改了哪些文件",连统计行数都嫌多,可以使用--name-only。相关技巧记录在 list-filenames-without-the-diffs.md:

$ git show HEAD --name-only commit c563bafb511bb984c4466763db7e8937e7c3a509 Author: jbranchaud <jbranchaud@gmail.com> Date: Sat May 16 20:56:07 2015 -0500 This is my sweet commit message app/models/user.rb README.md spec/factories/user.rb

该技巧以git show为例,但同样适用于git log:git log --name-only会为每个提交列出涉及的文件清单。若还想知道每个文件的变更类型(新增 A / 修改 M / 删除 D / 重命名 R),可改用--name-status:

$ git log --name-status

--name-only、--name-status、--stat、-p构成了从"文件名 → 统计 → 全文 diff"的完整信息阶梯,可按场景任意组合选用。

缩小 Diff 范围:路径过滤、范围语法与行号追踪

git log -p全量输出在历史较长的仓库中会非常冗长。本仓库的多个技巧笔记给出了三种实用的"瘦身"手段。

按路径/目录过滤

show-changes-for-files-that-match-a-pattern.md 指出,可以在命令末尾追加路径参数,只展示匹配文件的变更:

# 只看 CSS 文件的变更 $ git show abcd1234 *.css # 只看 src/css 目录内的变更 $ git show abcd1235 src/css

同样的路径过滤(pathspec)语法可直接用于git log,例如本仓库中只想看git/目录下的笔记变更:

$ git log -p -- git/

甚至可以叠加--follow跟踪文件重命名,或结合 show-changes-in-the-compose-commit-message-view.md 的思路按模式匹配文件。

用..与...限定提交范围

two-kinds-of-dotted-range-notation.md 详细区分了两种点号范围语法。两点语法A..B表示"在 B 中但不在 A 中的提交":

❯ git log master..some-feature-branch --oneline 9e50bff (some-feature-branch) Add second feature change b11bb0b Add first feature change

把两侧换位,即可反过来查看另一分支的新增提交:

❯ git log some-feature-branch..master --oneline c2880f8 (HEAD -> master) Add description to README

三点语法A...B表示"两侧各自独有的提交全集"(对称差):

❯ git log master...some-feature-branch --oneline c2880f8 (HEAD -> master) Add description to README 9e50bff (some-feature-branch) Add second feature change b11bb0b Add first feature change

将范围语法与-p组合,例如git log -p master..some-feature-branch,就能只查看某个分支相对另一分支的全部差异细节,是 Code Review 前的高频操作。

按行号追踪特定代码的演化

Git 1.8.4 起,git log支持-L标志,按"文件的行号范围"过滤提交,相关用法记录在 show-only-commits-that-touch-specific-lines.md:

# 查看所有改动过 README.md 第 13 行的提交 $ git log -L13,13:README.md # 查看改动过第 19~45 行的提交 $ git log -L19,45:README.md

-L非常适合追溯"某行代码/某条依赖是什么时候引入的"。该笔记作者提到,曾用它定位package.json中某个依赖的引入提交,尽管该行最近的改动只是版本号升级。-L同样可以与-p等效地展示每个命中提交的具体 diff。

控制阅读体验:分页器、外部 Diff 工具与 Diff 算法

git log -p输出通常很长,Git 默认用less分页器展示,支持上下滚动与/搜索。本仓库记录了三种优化阅读体验的方式。

配置分页器

configuring-the-pager.md 说明,Git 会为git-diff、git-log这类大输出命令自动启用分页器,默认是less,可以替换:

# 换用 more $ git config --global core.pager 'more' # 彻底关闭分页器(适合管道输出场景) $ git config --global core.pager ''

接入外部 Diff 工具

use-external-diff-tool-like-difftastic.md 记录了两步接入法:通过-c diff.external=<二进制>指定外部 diff 工具,同时必须加上--ext-diff标志才会真正生效:

$ git -c diff.external=difft show --ext-diff

关键陷阱是:仅配置diff.external而忘记--ext-diff,仍会回退到默认的 diff 渲染。这一规则同样适用于git log --ext-diff。

另一条更主流的思路记录在 better-diffs-with-delta.md:把delta同时配置为分页器与 diff 过滤器,可获得语法高亮、行内变更高亮等视觉增强:

[core] pager = delta [interactive] singleKey = true # unrelated, but nice to have diffFilter = delta --color-only

更换 Diff 算法

如果默认算法在大改动集上产生错位噪声,diffing-with-patience.md 建议使用patience算法——它聚焦于"两侧各只出现一次的高信息量行"作为特征签名来做最长公共子序列匹配,diff 结果通常更整洁,代价是略慢:

$ git config --global diff.algorithm patience

或直接写入~/.gitconfig:

[diff] algorithm = patience

该配置对所有 diff 渲染(包括git log -p的 diff 部分)全局生效。

在本仓库中的实战场景

以 til 仓库本身为例,git log -p的典型应用场景包括:

  • 回顾"新增笔记"类提交:这类提交通常同时包含新增的.md笔记文件与 README 计数更新,如文档示例中的_574 TILs and counting..._→_575 TILs and counting..._,一条命令即可完整看到"新笔记 + 计数更新"的全貌;
  • 确认特定目录的改动:配合git log -p -- git/之类路径过滤,只审查某个主题目录的笔记变更;
  • 审查分支差异:配合git log -p master..feature查看分支之间的全部内容差异。

更多配套技巧可继续查阅本仓库的 git 目录 下的笔记,例如 show-changes-for-files-that-match-a-pattern.md、list-filenames-without-the-diffs.md 等。关于-p标志的完整语义与可组合参数,可参阅man git-log。

  • 文档
  • 教程
  • 知识库

【免费下载链接】til

:memo: Today I Learned

项目地址:https://gitcode.com/gh_mirrors/ti/til
点击查看免费下载

相关推荐

上一篇:终极IPXWrapper教程:5分钟让经典游戏在现代Windows系统重获联机功能
下一篇:Autoclick终极指南:如何用Mac自动点击工具1秒完成900次点击

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询