Appearance
Git 生成指定提交之间的 patch 并应用
- 状态:已验证
- 来源:对话整理
- 更新时间:2026-03-16
关键结论
git diff commit1 commit2 > patch可以生成普通 patch。git diff生成 patch 时的参数顺序是old -> new。- 第一个 commit 表示原始版本,第二个 commit 表示目标版本。
- 如果两个 commit 顺序写反,生成的 patch 会变成回滚补丁。
git diff --binary可以把二进制文件变化包含进 patch。- 在 Git 仓库中,
git apply通常比通用的patch更适合应用 Git 生成的差异。 - 如果需要按 commit 粒度保留提交说明和作者信息,应使用
git format-patch配合git am。 git bundle不是 patch 的一种,而是仓库级传递与备份方式;相关内容应查看 bundle.md。
详细分析
Git 中常见的差异传递方式可以分为两类:
- 补丁类:普通 diff patch、commit patch
- 仓库级传递:repository bundle
本条目只讲补丁的生成与应用,不把 bundle 当作补丁类型展开。
普通 diff patch
- 生成方式:
bash
git diff commit1 commit2 > changes.patch- 特点:
- 只包含文件差异
- 不包含 commit message、作者等提交元信息
- 可使用
patch或git apply应用
git diff <old> <new>的语义是“把代码从old版本修改到new版本”。- 生成出的 patch 记录的是:
old中被删除的内容,用-表示new中新增的内容,用+表示
- 因此:
bash
git diff old_commit new_commit > changes.patch- 表示生成一个“从
old_commit前进到new_commit”的正向 patch。 - 如果写成:
bash
git diff new_commit old_commit > revert.patch- 则语义会变成“把
new_commit回退到old_commit”,得到的是反向 patch。
commit patch
- 生成方式:
bash
git format-patch commit1..commit2- 特点:
- 每个 commit 单独生成一个 patch 文件
- 保留 commit message、作者和时间等提交信息
- 应使用
git am应用,而不是git apply
repository bundle
- 生成方式:
bash
git bundle create repo.bundle --all特点:
- 保存完整 Git 对象和 refs
- 更适合离线仓库传输、完整迁移和备份
- 与 patch 不同,它保留的是仓库级数据而不是单纯文本差异
在代码迁移、跨仓库同步或离线传输时,如果只是需要把两个提交之间的改动内容送到另一边,普通 patch 足够;如果还需要保留提交历史语义,则应优先考虑
format-patch。如果需要传递的是完整 Git 仓库对象、refs 或离线备份,而不是单纯的文件差异,应优先查看 bundle.md。
可执行步骤
- 生成两个提交之间的 patch:
bash
git diff --binary old_commit new_commit > changes.patch- 在目标仓库检查 patch 是否可应用:
bash
git apply --check changes.patch- 在目标仓库应用 patch:
bash
git apply changes.patch- 如果需要以 commit 粒度导出 patch:
bash
git format-patch commit1..commit2- 在目标仓库按 commit 应用 patch:
bash
git am *.patch命令 / 配置 / 代码
bash
# 生成包含二进制内容的普通 patch
git diff --binary old_commit new_commit > changes.patch
# 检查 patch 是否可应用
git apply --check changes.patch
# 应用 patch
git apply changes.patch
# 生成 commit 级 patch
git format-patch commit1..commit2
# 应用 commit 级 patch
git am *.patch
# 生成完整仓库 bundle
git bundle create repo.bundle --all风险与注意事项
git diff的 commit 顺序写错,会直接生成反向 patch。- 如果不加
--binary,普通 diff patch 可能无法正确表达二进制文件变化。 - 普通 patch 不包含 commit history,只保留文件差异。
- patch 应用通常要求目标仓库具备兼容的目录结构和基础上下文,否则容易失败。
git apply只应用文件改动,不会自动生成 commit;应用后通常还需要手工提交。git format-patch与git am适合保留提交语义,但前提是目标仓库具备能接住这组 commit 的上下文历史。
关联条目
- 仓库级离线传递与备份见 Git bundle 离线仓库迁移与备份。