git format-patch生成含提交元数据(作者、时间、消息)的邮件格式.patch文件,适用于正式合入;git diff生成无元数据的.diff文件,仅记录内容差异,适合临时共享未提交修改。

补丁不是“导出代码”,而是记录“怎么改的”——用错命令或忽略上下文,补丁很可能打不上、打歪、或丢掉作者和提交信息。
git format-patch 和 git diff 生成的补丁有什么区别?
两者都输出 .patch 或 .diff 文件,但内容和用途完全不同:
-
git format-patch生成的是「邮件格式补丁」:包含提交哈希、作者、日期、提交信息,甚至签名。适合跨团队分发、保留完整历史,git am能直接还原成带元数据的提交。 -
git diff(不带参数)只对比工作区与HEAD,输出纯差异;git diff --staged对比暂存区与HEAD。这类补丁不含元数据,git apply可用,但git am会报错fatal: Not a valid commit message。 - 如果目标是快速共享未提交的修改(比如临时给同事看一个 bug 修复),用
git diff > fix.patch最轻量;如果是准备合入主干的正式改动,必须用git format-patch。
git apply 和 git am 应该选哪个?
关键看你要不要「自动提交」和「保留原始作者信息」:
-
git apply fix.patch:只修改文件,不创建提交,也不动暂存区。你需要自己git add+git commit。适合测试补丁是否能干净应用,或只想拿改动内容而不关心来源。 -
git am 0001-*.patch:不仅应用修改,还会读取补丁里的作者、时间、提交信息,自动生成新提交。适用于接收git format-patch产出的补丁,尤其在 CI 流水线或维护者审核后合入时。 - 容易踩的坑:
git am要求补丁路径与当前仓库结构严格匹配(比如补丁里写a/src/string.py,你仓库里就得有src/string.py)。而git apply支持--directory=参数做路径偏移,更灵活。
补丁打不上去?先检查这三件事
报错常见但原因集中,别急着手动改文件:
- 运行
git apply --check fix.patch:不实际修改,只验证能否应用。失败时会明确指出哪行/哪个文件不匹配。 - 检查基础版本是否一致:补丁是基于
commit A生成的,目标仓库当前HEAD必须是A或其祖先。用git merge-base HEAD <commit-a></commit-a>可确认是否有共同祖先。 - 空白符或换行符干扰:Windows/Linux 换行符混用、IDE 自动 trim 空格,都可能让
git apply拒绝。加--ignore-whitespace参数试试,或用git apply --whitespace=fix自动修正。
补丁的本质是「上下文敏感的文本替换」,不是万能胶。最常被忽略的是:它不解决逻辑冲突(比如两个补丁都改了同一函数的返回值),只解决行号/内容位置的匹配问题。真要集成多处变更,还是得靠 git rebase 或 git cherry-pick ——补丁只是过渡手段,不是替代分支协作的方案。


















