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 文件,你可以方便地在不同分支、甚至不同仓库之间迁移代码变更,特别适合无法直接推送代码的场景(如代码审核、离线环境等)。

posted @ 2025-07-30 11:14  michaelchengjl  阅读(326)  评论(0)    收藏  举报