当前位置: 首页 > 工具软件 > GNU patch > 使用案例 >

使用 patch 命令打补丁

贺景胜
2023-12-01

之前的这篇文章 git 导出差异 diff 文件 写了导出 diff 、patch 文件。

拿到 patch 文件,用 patch 命令可以快速的把修改内容合入,合入后在 git 上是已修改的状态,如需提交还要 add 、commit 。

patch 语法

patch --help 可以看到

Usage: patch [OPTION]... [ORIGFILE [PATCHFILE]]

Input options:

  -p NUM  --strip=NUM  Strip NUM leading components from file names.
  -F LINES  --fuzz LINES  Set the fuzz factor to LINES for inexact matching.
  -l  --ignore-whitespace  Ignore white space changes between patch and input.

  -c  --context  Interpret the patch as a context difference.
  -e  --ed  Interpret the patch as an ed script.
  -n  --normal  Interpret the patch as a normal difference.
  -u  --unified  Interpret the patch as a unified difference.

  -N  --forward  Ignore patches that appear to be reversed or already applied.
  -R  --reverse  Assume patches were created with old and new files swapped.

  -i PATCHFILE  --input=PATCHFILE  Read patch from PATCHFILE instead of stdin.

Output options:

  -o FILE  --output=FILE  Output patched files to FILE.
  -r FILE  --reject-file=FILE  Output rejects to FILE.

  -D NAME  --ifdef=NAME  Make merged if-then-else output using NAME.
  -m  --merge  Merge using conflict markers instead of creating reject files.
  -E  --remove-empty-files  Remove output files that are empty after patching.

  -Z  --set-utc  Set times of patched files, assuming diff uses UTC (GMT).
  -T  --set-time  Likewise, assuming local time.

  --quoting-style=WORD   output file names using quoting style WORD.
    Valid WORDs are: literal, shell, shell-always, c, escape.
    Default is taken from QUOTING_STYLE env variable, or 'shell' if unset.

Backup and version control options:

  -b  --backup  Back up the original contents of each file.
  --backup-if-mismatch  Back up if the patch does not match exactly.
  --no-backup-if-mismatch  Back up mismatches only if otherwise requested.

  -V STYLE  --version-control=STYLE  Use STYLE version control.
        STYLE is either 'simple', 'numbered', or 'existing'.
  -B PREFIX  --prefix=PREFIX  Prepend PREFIX to backup file names.
  -Y PREFIX  --basename-prefix=PREFIX  Prepend PREFIX to backup file basenames.
  -z SUFFIX  --suffix=SUFFIX  Append SUFFIX to backup file names.

  -g NUM  --get=NUM  Get files from RCS etc. if positive; ask if negative.

Miscellaneous options:

  -t  --batch  Ask no questions; skip bad-Prereq patches; assume reversed.
  -f  --force  Like -t, but ignore bad-Prereq patches, and assume unreversed.
  -s  --quiet  --silent  Work silently unless an error occurs.
  --verbose  Output extra information about the work being done.
  --dry-run  Do not actually change any files; just print what would happen.
  --posix  Conform to the POSIX standard.

  -d DIR  --directory=DIR  Change the working directory to DIR first.
  --reject-format=FORMAT  Create 'context' or 'unified' rejects.
  --binary  Read and write data in binary mode.
  --read-only=BEHAVIOR  How to handle read-only input files: 'ignore' that they
                        are read-only, 'warn' (default), or 'fail'.

  -v  --version  Output version info.
  --help  Output this help.

Report bugs to <bug-patch@gnu.org>.

应用到打补丁上常用 patch -p1 < xxx.diff

示例

如 test_patch.diff 文件内容如下,

diff --git a/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java b/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
index cb3348f7ab..a0c35bafa4 100755
--- a/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2602,6 +2602,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
     @Override
     public long interceptKeyBeforeDispatching(IBinder focusedToken, KeyEvent event,
             int policyFlags) {
+        Log.d(TAG, "test_patch");
         final boolean keyguardOn = keyguardOn();
         final int keyCode = event.getKeyCode();
         final int repeatCount = event.getRepeatCount();

把 test_patch.diff 放在和 frameworks/ 同级别的目录下,

同级别目录

使用 patch -p1 < test_patch.diff 命令,提示

aaa@compilerbbb:~/ccc/ANDROID$ patch -p1 < test_patch.diff
patching file frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

说明打补丁完成,使用 git diff 看,是OK的。

子目录1

进入 frameworks/ 目录下,使用 patch -p1 < test_patch.diff 命令,提示

aaa@compilerbbb:~/ccc/ANDROID$/frameworks$ patch -p1 < ../test_patch.diff
can't find file to patch at input line 5
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|diff --git a/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java b/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
|index cb3348f7ab..a0c35bafa4 100755
|--- a/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
|+++ b/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
--------------------------
File to patch:

输入 base/services/core/java/com/android/server/policy/PhoneWindowManager.java 即可解决,

aaa@compilerbbb:~/ccc/ANDROID$/frameworks$ patch -p1 < ../test_patch.diff
can't find file to patch at input line 5
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|diff --git a/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java b/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
|index cb3348f7ab..a0c35bafa4 100755
|--- a/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
|+++ b/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
--------------------------
File to patch: base/services/core/java/com/android/server/policy/PhoneWindowManager.java
patching file base/services/core/java/com/android/server/policy/PhoneWindowManager.java

子目录2

子目录1 中,因为实际路径和 patch 文件路径有差异,需要手动输一下路径。

有没有不用输入路径的方法?有的,用 patch -p2 < ../test_patch.diff

aaa@compilerbbb:~/ccc/ANDROID$/frameworks$ patch -p2 < ../test_patch.diff
patching file base/services/core/java/com/android/server/policy/PhoneWindowManager.java
aaa@compilerbbb:~/ccc/ANDROID$/frameworks/base$ patch -p3 < ../../test_patch.diff 
patching file services/core/java/com/android/server/policy/PhoneWindowManager.java
 类似资料: