Appearance
补丁(Patch)
补丁(Patch)是以文件形式存储的代码差异,可以在不同机器或仓库之间传递改动。在没有共享代码库访问权限时,补丁是传递代码改动的经典方式。
git diff > file.patch 生成补丁
用 git diff 生成标准 diff 格式的补丁:
bash
# 工作区改动 vs 暂存区
git diff > changes.patch
# 暂存区 vs HEAD
git diff --cached > staged.patch
# 指定提交之间的差异
git diff abc123..def456 > feature.patch
# 指定文件的差异
git diff HEAD~3 -- src/app.js > app-changes.patchgit apply 应用补丁
将补丁文件应用到当前工作区:
bash
# 应用补丁
git apply changes.patch
# 应用补丁并自动暂存
git apply --index changes.patch
# 应用补丁(更详细的输出)
git apply -v changes.patchgit format-patch 生成邮件格式补丁
git format-patch 生成的补丁包含完整的提交信息(作者、时间、提交消息),适合通过邮件发送:
bash
# 生成最近 3 个提交的补丁(每个提交一个 .patch 文件)
git format-patch -3
# 生成:
# 0001-feat-add-login.patch
# 0002-feat-add-register.patch
# 0003-fix-validation.patch
# 生成某个范围的提交
git format-patch main..feature/login
# 生成单个文件(所有提交合并)
git format-patch -1 --stdout > single.patch
# 指定输出目录
git format-patch -3 -o patches/
# 基于某个提交生成补丁
git format-patch abc123..HEAD
# 只生成某个特定提交的补丁
git format-patch -1 abc123补丁文件内容示例:
From abc123456789 Mon Sep 17 00:00:00 2001
From: Zhang San <zhang@example.com>
Date: Mon, 9 Mar 2026 10:30:00 +0800
Subject: [PATCH] feat: 添加用户登录功能
实现了基于 JWT 的用户认证
---
src/auth.js | 45 +++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/src/auth.js b/src/auth.js
...git am 应用邮件格式补丁
git am(Apply Mailbox)将 format-patch 生成的补丁应用为完整提交(包含作者信息):
bash
# 应用单个补丁文件
git am 0001-feat-add-login.patch
# 应用目录下所有补丁
git am patches/*.patch
# 从邮件中应用(通过 stdin)
cat 0001-*.patch | git am
# 应用并签名
git am --signoff 0001-*.patchgit am vs git apply 的区别:
| 对比项 | git apply | git am |
|---|---|---|
| 输入格式 | 标准 diff | format-patch 格式 |
| 创建提交 | 否(只修改工作区) | 是(创建完整提交) |
| 保留作者信息 | 否 | 是 |
| 适用场景 | 快速应用差异 | 应用他人的提交 |
git apply --check 测试补丁
在实际应用前,先验证补丁是否能正常应用:
bash
# 检查补丁是否能应用(不实际修改)
git apply --check changes.patch
# 成功:无输出
# 失败:error: patch failed: src/app.js:10git apply --reject 部分应用
当补丁无法完全应用时(有冲突),--reject 允许应用可以应用的部分,并将冲突部分保存为 .rej 文件:
bash
# 尽力应用,冲突部分保存为 .rej 文件
git apply --reject changes.patch
# 查看冲突部分
cat src/app.js.rej
# 手动合并后,删除 .rej 文件
rm src/app.js.rej
git add src/app.js实际工作流示例
场景1:向没有仓库访问权限的人发送改动
bash
# 开发者 A:生成补丁
git format-patch -3 -o ~/patches/
# 通过邮件发送 patches/ 目录中的文件
# 开发者 B:应用补丁
git am ~/patches/*.patch
git log --oneline -3 # 看到完整的提交历史,包含原作者信息场景2:快速测试某个 PR 的改动
bash
# 从 PR 的差异生成补丁(GitHub 支持直接下载 .patch 文件)
# URL: https://github.com/user/repo/pull/123.patch
curl -o pr-123.patch https://github.com/user/repo/pull/123.patch
# 先检查
git apply --check pr-123.patch
# 应用测试
git am pr-123.patch
# 测试完后回退
git reset --hard HEAD~<commit-count>场景3:保存工作进度为补丁
bash
# 将未提交的工作保存为补丁(备用方案)
git diff > wip-2026-03-09.patch
# 之后恢复
git apply wip-2026-03-09.patch总结
| 操作 | 命令 |
|---|---|
| 生成 diff 补丁 | git diff > file.patch |
| 应用 diff 补丁 | git apply file.patch |
| 生成邮件格式补丁 | git format-patch -n |
| 应用邮件格式补丁 | git am file.patch |
| 检查补丁可应用性 | git apply --check file.patch |
| 部分应用 | git apply --reject file.patch |
在现代 Git 工作流中,补丁的使用场景已经大幅减少(被 PR/MR 替代),但在一些特殊场景下(离线协作、邮件列表项目如 Linux 内核),补丁仍然是重要的工具。