如何为指定提交生成 Git 补丁文件
为单个提交生成补丁:git format-patch -1 <提交哈希>,生成 0001-说明.patch 文件;对方用 git am < 补丁文件 应用为完整提交(保留作者与提交信息)。只要 diff 用 git show > fix.patch。
用 git format-patch -1 <提交哈希>:生成一个 0001-提交说明.patch 文件,里面不仅有 diff,还包含作者、日期、提交信息——对方用 git am 应用后能还原成保留作者与提交说明的新提交(父提交、提交者及哈希可能变化)。只要纯 diff 不要元信息时用 git show --format= <哈希> > fix.patch。
以下 format-patch 示例针对普通非合并提交;合并提交不能按此直接完整搬运拓扑。
常用场景
# 单个指定提交
git format-patch -1 a1b2c3d
# 最近 3 个提交
git format-patch -3
# 某个范围
git format-patch main..feature-x
# 输出到指定目录
git format-patch -1 a1b2c3d -o patches/
应用补丁
git am < 0001-fix-login-bug.patch # 还原为完整提交
git am --3way < fix.patch # 冲突时尝试三方合并
git apply 0001-xxx.patch # 只应用文件改动,不产生提交
format-patch vs show/diff
| 命令 | 产物 | 应用方式 | 保留提交信息 |
|---|---|---|---|
format-patch |
邮件格式补丁 | git am |
✅ 保留作者和说明,不保证原哈希 |
git show --format= <哈希> > x.patch |
纯 diff | git apply |
❌ |
git diff |
纯 diff | git apply |
❌ |
跨仓库"搬运提交"用 format-patch;只是分享代码改动用 apply 系列即可。
常见问题(FAQ)
Q:am 应用时冲突怎么办?
git am --3way 在补丁记录了基准 blob 且本地存在相应对象时尝试三方合并;仍有冲突则进入冲突解决流程,解决后 git am --continue,放弃用 git am --abort。
Q:补丁里带二进制文件怎么办?
format-patch 默认就支持二进制(自动用 binary patch 编码),生成普通 diff 的二进制补丁需用 git diff --binary;现代 git apply 可以应用已包含 binary patch 的补丁,--binary 只是兼容性参数。
Q:能把补丁通过邮件发给维护者吗?
这正是 format-patch 的设计初衷(Linux 内核工作流):git send-email 可以直接发送。现代团队更多用 PR,但邮件列表社区仍大量使用。