概述
git format-patch 用于将每次非合并提交(non-merge commit)的补丁准备在一个文件中,格式类似于 UNIX 邮箱格式。该命令的输出便于通过电子邮件提交补丁,或与 git am 配合使用来应用补丁。
与 git diff 生成的 .diff 文件不同,git format-patch 生成的 .patch 文件不仅记录文件变更内容,还包含完整的 commit 记录信息(作者、日期、提交信息等),每个 commit 对应一个独立的 patch 文件。
基本语法
git format-patch [选项] [<since> | <revision-range>]
指定要生成补丁的提交范围
1. 单个提交 <since>
生成当前分支中领先于指定提交的所有提交的补丁。
2. 提交范围 <revision-range>
使用标准的 Git 版本范围表达式来指定要生成补丁的提交范围。
常用场景与示例
生成最近 N 次提交的补丁
# 最近1次提交
git format-patch HEAD^
# 最近2次提交
git format-patch HEAD^^
# 最近3次提交
git format-patch HEAD^^^
# 最近4次提交
git format-patch HEAD^^^^
生成单个提交的补丁
git format-patch -1 <commit-id>

生成两个提交之间的所有补丁(不包含起始提交)
git format-patch <commit-A>..<commit-B>

生成某次提交以来的所有补丁(不包含该提交)
git format-patch <commit-id>
从根提交到指定提交的所有补丁
git format-patch --root <commit-id>
当前分支相对于 master 的所有新提交
git format-patch -M master
典型工作流示例:将分支上的新提交导出为补丁
# 切换到基准分支(缺少新提交的分支)
git checkout master
# 为 bugfix 分支中所有新提交生成补丁文件
git format-patch bugfix/broken-navigation
常用选项
| 选项 | 说明 |
|---|---|
-o <dir> / --output-directory <dir> |
将补丁文件输出到指定目录 |
--stdout |
将所有补丁输出到标准输出(可重定向到单个文件) |
--numbered-files |
输出文件名仅使用编号,不包含提交信息第一行 |
--start-number <n> |
指定起始编号 |
-s / --signoff |
在提交信息中添加 Signed-off-by 签名 |
-v <n> / --reroll-count <n> |
标记补丁的修订版本号 |
--subject-prefix <前缀> |
修改邮件主题前缀(默认 [PATCH]) |
--to=<email> / --cc=<email> |
在补丁中添加收件人/抄送信息 |
--cover-letter |
生成封面信(cover letter) |
--thread |
生成 In-Reply-To 和 References 头,用于邮件线程 |
--suffix=.<sfx> |
指定补丁文件后缀(默认 .patch) |
--quiet |
静默模式,不输出进度信息 |
补丁文件命名规则
默认情况下,补丁文件从 1 开始顺序编号,并使用对应提交信息的第一行作为文件名。例如:
0001-fix-navigation-bug.patch
0002-update-readme.patch
如果使用 --numbered-files 选项,文件名仅为编号:
0001
0002
应用补丁(git am)
由 git format-patch 生成的补丁,应使用 git am 来应用:
# 应用单个补丁
git am 0001-fix-navigation-bug.patch
# 应用目录下所有补丁(按顺序)
git am ~/patch-set/*.patch
# 添加签名信息
git am --signoff 0001-fix-navigation-bug.patch
git am 的特点 :会保留补丁中的作者信息、提交信息等完整 commit 元数据,应用后无需再手动 git add 和 git commit。
应用补丁时的冲突处理
-
如果遇到冲突,Git 会停止并提示
-
解决冲突后执行
git am --resolved继续 -
如果想放弃本次 am 操作:
git am --abort -
如果想跳过当前补丁:
git am --skip
git format-patch 与 git diff 的区别
| 特性 | git format-patch |
git diff |
|---|---|---|
| 包含 commit 信息 | ✅ 是 | ❌ 否 |
| 每个 commit 独立文件 | ✅ 是 | ❌ 多个 commit 可合并为一个文件 |
| 适用应用命令 | git am |
git apply |
| 用途 | 邮件提交、代码审查 | 快速查看差异 |
注意事项
-
git format-patch会忽略合并提交(merge commit),只处理非合并提交 -
生成的补丁文件默认保存在当前工作目录,可通过
-o指定输出目录 -
补丁文件内容包含三部分:元数据头、提交日志信息、以及
diff -p --stat格式的补丁内容 -
如果指定了
--stdout,所有补丁将合并输出到标准输出,可重定向为单个文件