Home Git 打补丁
Post
Cancel

Git 打补丁

关于补丁

补丁用来显示两个文件不同的地方,配合相关命令,快速更新文件。

补丁有两种形式:

  1. UNIX标准补丁.diff文件,用git diff生成
  2. Git专用.patch 文件,用git format-patch生成

git工具同时支持diff文件和patch文件。

git patch

通过 git diff 生成的文件不含有 commit 信息,可以指定文件生成 diff,也可以指定单个 commit, 多个 commit 生成 。
通过 git format-patch 生成的 .patch 文件 含有 commit 信息。一个 commit 对应一个 patch 文件。

可以 git diffgit apply配合使用。git format-patchgit am配合使用。

创建补丁

可以使用 git diff , git format-patch。。。

如 使用 git diff的常见方式:

1
2
3
4
5
6
7
git diff > xxx.patch
# 可以加上文件名,commit等参数
git diff [xxx_file] > xxx.patch
git diff [commit sha1 id] > xxx.patch

# 还可以两次commit 之间的
git diff [commitA sha1 id] [commitB sha1 id] > xxx.patch

使用 git format-patch 的常见方式:

1
2
3
4
5
6
# 某次提交(含)之前的几次提交,n指从sha1 id对应的commit开始算起n个提交。
git format-patch [commit sha1 id] -n

# 两次提交之间的所有patch
git format-patch [commit sha1 id]..[commit sha1 id]

应用补丁

可以使用 git apply , git am 命令。。。

使用git apply:

1
2
3
4
5
6
7
8
# 先检查patch文件格式
git apply --stat xxx.patch

# 测试patch是否能应用
git apply --check xxx.patch

# 最后打上补丁
git apply xxx.patch

这种方式传递的修改将会丢失提交信息和作者信息,但可以兼容非 git 管理的代码。

使用git am: format-patch 生成的 patch 保存了更多提交信息。因此除了 git apply 之外,还可以用更智能的 git am 命令使用此 patch, 会在修改文件的同时将 commit 信息也一起应用到 git 中。git am 可以复现修改,保留作者信息,保留 commit 信息,但 commit ID 无法保留。 git am 命令会在应用patch 失败时给出详细的错误信息,并允许手动解决冲突,是官方较为推荐的补丁应用方式。

1
2
....

diff

主要使用diff工具和patch工具制作和应用补丁。

制作补丁

diff 是一个文件比较工具,可以逐行比较两个文件的不同,其中它有三种输出方式,分别是normalcontext以及unified。 区别如下:

  • normal 方式为默认输出方式,不需要加任何参数
  • context 相较于 normal 模式的简单输出,contetx 模式会输出修改过部分的上下文,默认是前后 3 行。使用参数 -c
  • unified 合并上下文模式则为新的上下文输出模式,同样为前后 3 行,只不过把上下文合并了显示了。使用参数 -u

一般使用 unified模式。

其他常用参数:

  • -r 递归处理目录
  • -N 将缺失的文件当作空白文件处理

基本用法:

1
diff [options] old new

通常参数使用 -urN ,一般需要将输出保存到补丁文件,如

1
2
diff -urN path/to/old/file path/to/new/file  > mypatch.patch
diff -urN path/to/old/file path/to/new/file  > mypatch.diff

应用补丁

patch 是一个可以将 diff 生成的补丁应用到源文件,生成一个打过补丁版本的文件。语法:

1
patch [oiption] [originalfile [patchfile]]

常用参数:

  • -i 指定补丁文件
  • -pNum 在 diff 生成的补丁中,第一二行是文件信息,其中文件名是可以包含路径的, 例如 --- /tmp/test1 2018-05-12 18:39:41.508375114 +0800 , 其中 -p0 代表完整的路径 /tmp/test1,而 -p1 则指 tmp/test1-pN 依此类推
  • -R 回退补丁
  • -E 删除应用补丁后为空文件的文件
  • -o 输出到一个文件而不是直接覆盖文件

使用patch时主要要注意当前路径和patch中的路径,路径不能有偏差,示例:

1
2
3
4
5
6
7
8
9
10
# 文件打补丁
patch path/to/old/file -i mypatch.patch [-o to/a/new/file]

# 常见用法-打补丁
patch -p0 -i mypatch.patch
# 或
patch -p0 < mypatch.patch

# 常见用法-回退补丁
patch -p0 -R -i mypatch.patch

ref: diff 与 patch 的使用

This post is licensed under CC BY 4.0 by the author.