git patch
git patch
在 Git 中,打补丁(Patch)是将代码变更以文件形式保存和共享的方式。以下是详细的操作步骤和示例:
1. 生成 Patch 文件
1.1 未提交的修改生成 Patch
# 生成工作区所有未暂存的修改
git diff > changes.patch
# 生成已暂存的修改(stage区)
git diff --cached > staged_changes.patch
# 生成工作区+暂存区的所有修改
git diff HEAD > all_changes.patch
1.2 已提交的修改生成 Patch
# 生成最近1次提交的patch
git format-patch HEAD~1 -o patches/
# 生成两个提交之间的patch(不含start_commit)
git format-patch start_commit..end_commit -o patches/
# 生成某次提交的patch(按提交哈希)
git format-patch -1 <commit_hash> -o patches/
参数说明:
-o patches/:指定输出目录
HEAD~1:最近1次提交
start_commit..end_commit:提交范围
2. 应用 Patch 文件
2.1 检查 Patch 内容
# 查看patch内容(确认变更)
git apply --stat changes.patch
# 检查是否能成功应用(不实际修改文件)
git apply --check changes.patch
2.2 应用 Patch
# 方式1:直接应用(不保留提交信息)
git apply changes.patch
# 方式2:应用并保留提交信息(需format-patch生成的patch)
git am patches/0001-Add-new-feature.patch
区别:
命令 保留提交信息 适用场景
git apply ❌ 非提交的diff文件
git am ✅ format-patch生成的文件
3. 冲突处理
如果应用 patch 时出现冲突:
# 使用git am时遇到冲突
git am --abort # 终止应用
git am --continue # 解决冲突后继续
# 使用git apply时手动解决冲突
git apply --reject changes.patch # 生成.rej文件
# 手动修改冲突文件后,删除.rej文件
4. 实际示例
场景:将某个功能修改分享给同事
步骤1:生成 Patch
# 生成最近2次提交的patch
git format-patch HEAD~2 -o /tmp/patches
# 生成文件:/tmp/patches/0001-commit-message1.patch
# /tmp/patches/0002-commit-message2.patch
步骤2:发送 Patch 文件
# 打包压缩
tar -czvf patches.tar.gz /tmp/patches/*.patch
# 通过邮件或IM工具发送
步骤3:接收方应用 Patch
# 解压并应用所有patch
tar -xzvf patches.tar.gz
git am /tmp/patches/*.patch
5. 高级技巧
5.1 生成二进制文件变更
git diff --binary > binary_changes.patch
5.2 从特定文件生成 Patch
git diff --no-prefix -- path/to/file.txt > file_changes.patch
5.3 打补丁时保留原作者信息
git am --keep-cr --committer-date-is-author-date patches/*.patch
5.4 生成 GitHub PR 的 Patch
# 获取PR的patch文件(需curl)
curl -L https://github.com/user/repo/pull/123.patch > pr_123.patch
6. 可视化流程
sequenceDiagram
participant DevA as 开发者A
participant Git as Git仓库
participant DevB as 开发者B
DevA->>Git: 开发并提交代码
DevA->>DevA: git format-patch (生成patch)
DevA->>DevB: 发送patch文件
DevB->>DevB: git am (应用patch)
DevB->>Git: 推送变更
常见问题
为什么 git am 失败?
可能原因:缺少依赖提交、存在冲突
解决方案:按顺序应用patch或手动解决冲突
如何撤销已应用的 Patch?
git am --abort
# 或
git reset --hard HEAD^
Patch 和 Cherry-pick 的区别?
patch:文件形式,可跨仓库共享
cherry-pick:直接复制提交,需访问同一仓库
通过 Patch 文件,你可以方便地在不同分支、甚至不同仓库之间迁移代码变更,特别适合无法直接推送代码的场景(如代码审核、离线环境等)。

浙公网安备 33010602011771号