>> >> >>Indexer<< << << <<<<<< Idx >>>>>>
Matched: 0
diff
M: 2025-12-31 - ljf12825

git diff用来比较两个版本之间的差异,以文本形式显示修改了哪些行

它的本质是:

  • 计算两份文件的差异(patch)
  • 按行标记增加(+)、删除(-
  • 使用颜色高亮(终端支持时)

它不只是比较已提交的版本,还可以比较工作区、暂存区、历史提交等不同状态

Git的三个状态\

名称存储位置作用常用命令查看
工作区(Working Directory)本地文件系统你正在编辑的文件ls、编辑器
暂存区(Staging Area / Index).git/index准备提交的文件快照git status
本地仓库(Repository / HEAD).git/objects已提交的版本历史git log

常用对比场景
git diff的核心是比较这三者之间的差别

命令比较对象作用场景举例
git diff工作区 vs 暂存区查看修改但未 git add 的内容检查还没加入暂存区的改动
git diff --cachedgit diff --staged暂存区 vs 本地仓库(HEAD)查看已 git add 但未提交的内容检查提交前的改动
git diff HEAD工作区 vs HEAD查看所有未提交的改动(包含未暂存 + 暂存)总览全部本地变更
git diff commitA commitB两个提交比较历史版本看某次功能从 v1 改成 v2 的细节
git diff branchA branchB两分支最新提交分支差异合并前检查差别
git diff tagA tagB两个标签版本对比比较正式版本

常用参数\

参数作用示例
--name-only只显示修改的文件名git diff --name-only
--name-status显示文件名 + 修改类型(A/M/D)git diff --name-status
--stat统计每个文件的修改行数git diff --stat
-p(默认)生成补丁格式git diff -p
--color-words按词高亮而不是按行git diff --color-words
--word-diff显示逐词修改git diff --word-diff
-U<num>控制上下文行数git diff -U0(只显示改动的行)
--ignore-space-change / --ignore-all-space忽略空格差异git diff --ignore-all-space
--no-index比较两个任意文件,不需要 git 仓库git diff --no-index a.txt b.txt

示例
假设改了一个文件main.c

diff --git a/main.c b/main.c
index 83db48f..bf269f1 100644
--- a/main.c
+++ b/main.c
@@ -2,7 +2,7 @@
int main() {
-   printf("Hello World\n");
+   printf("Hello Git\n");
    return 0;
}

含义:

  1. diff --git a/main.c b/main.c
  • 比较a/main.c(旧版本)和b/main.c(新版本)
  1. index
  • 显示旧文件和新文件的blod对象ID
  1. ---/+++
  • ---是旧版本文件路径
  • +++是新版本文件路径
  1. @@ -2,7 +2,7 @@
  • -2,7:旧文件从第2行起,共7行
  • +2,7:新文件从第2行起,共7行
  1. -开头的行:被删除的内容
  2. +开头的行:新增的内容

底层原理

git diff的原理是

  1. Git把对比的对象(工作区/暂存区/提交)转换成快照(blob对象)
  2. 调用内部的diff算法(最长公共子序列LCS变种)
  3. 输出一个统一格式(Unified Diff Format)的补丁

所以它和diff命令类似,但Git做了很多优化

  • 对二进制用binary diff
  • 先比较哈希(O(1))再比较文件内容(O(n))
  • 支持rename detection(检测文件重命名)

patch file

  • 生成补丁文件
git diff commitA commitB > change.patch
git apply change.patch

patch file

补丁文件(patch file)是记录文件差异的文本文件,用来告诉别人(或自己)这个项目/文件需要怎么改
它不是完整的文件副本,而是一个差异描述,按照一定的格式(常见是Unified Diff Format)存储哪些行进行增删
补丁文件本质上就是git diff的文本化保存

补丁文件的作用

  • 版本迁移:把一个版本的改动应用到另一个版本上
  • 代码分享:发给别人,让他们再自己的代码上复现你的改动
  • 代码审查:方便阅读具体改动(很多代码评审系统背后就是用diff/patch)
  • 离线协作:没法用Git仓库时,也能传递修改

补丁文件的使用
假设有了一个hello.patch文件,别人可以在自己的项目种应用

git apply hello.patch # 只应用改动
git am hello.patch # 应用并生成一次提交(带作者信息)

如果不是Git项目,也能用Linuxpatch命令

patch -p1 < hello.patch

补丁文件的优势\

  • 体积小(只存差异)
  • 可读性高
  • 跨平台、跨工具
  • 方便审查和版本回滚

Git中生成补丁的几种方式\

命令作用
git diff > file.patch生成工作区与暂存区/HEAD 的差异补丁
git diff commitA commitB > file.patch比较两个提交之间的差异
git format-patch commitA..commitB生成带提交记录、作者、时间的完整补丁(更适合邮件发送)
  • 比较某个历史文件
git diff HEAD~3 HEAD -- src/game.cpp
  • 只看新增的函数(配合grep
git diff HEAD~1 | grep '^+'