关于补丁
补丁用来显示两个文件不同的地方,配合相关命令,快速更新文件。
补丁有两种形式:
- UNIX标准补丁.diff文件,用git diff生成
- Git专用.patch 文件,用git format-patch生成
git工具同时支持diff文件和patch文件。
git patch
通过 git diff 生成的文件不含有 commit 信息,可以指定文件生成 diff,也可以指定单个 commit, 多个 commit 生成 。
通过 git format-patch 生成的 .patch 文件 含有 commit 信息。一个 commit 对应一个 patch 文件。
可以 git diff
和git apply
配合使用。git format-patch
和git 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 是一个文件比较工具,可以逐行比较两个文件的不同,其中它有三种输出方式,分别是normal,context以及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 的使用