Patch和Git打补丁学习笔记

1.Linux patch命令

Linux patch命令用于修补文件。

patch指令让用户利用设置修补文件的方式,修改,更新原始文件。倘若一次仅修改一个文件,可直接在指令列中下达指令依序执行。如果配合修补文件的方式则能一次修补大批文件,这也是Linux系统核心的升级方法之一。

 

2.Patch命令常用方法

是指在不使用Git工具的情况下,进行打补丁的操作,【单纯】地使用【patch和diff】这一对命令。

2.1patch命令常用选项含义

  • -r 是一个递归选项,设置了这个选项,diff会将两个不同版本源代码目录中的所有对应文件全部都进行一次比较,包括子目录文件。
  • -N 选项确保补丁文件将正确地处理已经创建或删除文件的情况。
  • -u 选项以统一格式创建补丁文件,这种格式比缺省格式更紧凑些。
  • -p0 选项从当前目录查找目的文件(夹)(直接使用补丁文件里面指定的路径)
  • -p1 选项忽略掉第一层目录,从当前目录查找(去掉补丁文件指定路径最左的第1个'/'及前面所有内容)。
  • -E  选项说明如果发现了空文件,那么就删除它。
  • -R  选项说明在补丁文件中的“新”文件和“旧”文件现在要调换过来了(实际上就是给新版本打补丁,让它变成老版本)
  • --dry-run:尝试运行打补丁,会显示执行的结果,输出提示信息,但并不真正打补丁,不修改实际文件。

定向符" < " 和 " > "的含义:

  • " < "后面跟着要“删除”的内容。
  • " > "后面跟着要“增加”的内容。
  • diff命令后面如果不加 “> xxx.patch”,就是只将差异打印出来,而不添加到补丁文件。

2.2对单个文件打补丁

  • 制作补丁:diff –uN from-file to-file > xxx.patch
  • 打补丁:patch –p1 < xxx.patch    
  • 还原补丁:patch –Rp1 < xxx.patch

2.3对整个文件夹打补丁

  • 制作补丁:diff –uNr from-docu to-docu > xxx.patch 
  • 打补丁:patch –p1 < xxx.patch 
  • 还原补丁:patch –Rp1 < xxx.patch 

 

3.Git下的打补丁

Git 提供了两种补丁方案,一是用git diff生成的UNIX标准补丁.diff文件,二是git format-patch生成的Git专用.patch 文件。

.diff文件只是记录文件改变的内容,不带有commit记录信息,多个commit可以合并成一个diff文件。

.patch文件带有记录文件改变的内容,也带有commit记录信息,每个commit对应一个patch文件。

在Git下,我们可以使用.diff文件也可以使用.patch 文件来打补丁。

使用 【git log 】命令 可以查看 commit ID,commit ID 会比较长,使用时可仅使用其前几个字母表示

3.1 git format-patch 方法

生成只适用于git的patch,包含diff信息,包含提交人,提交时间等。如果git format-patch 生成的补丁不能打到当前分支,git am会给出提示,并协助你完成打补丁工作。

  • git format-patch 官方文档:https://git-scm.com/docs/git-format-patch
  • git am 官方文档:https://git-scm.com/docs/git-am

制作补丁:

  • git format-patch [commit_id]  -n    // 制作某次提交(含)之前的n次提交,如果是某个commit则n的值为1
  • git format-patch [commit_id]         // 制作某次提交(不含)之后后的所有提交的补丁
  • git format-patch -n                        // 制作最后一次提交(含)之前的n次提交的补丁
  • git format-patch HEAD^               // 制作最后一次提交补丁
  • git format-patch HEAD^^             // 制作最后两次提交补丁
  • git format-patch [x_commit_id] .. [xx_commit_id]    // 制作某两次commit之间的所有commit的patch,注意中间有两个点
  • 说明:该方法会生成名为例如【0001-xxx.patch】的一个或多个补丁文件,该命名与你的commit对应。

打补丁:使用 git am 命令,这种方法会在你打补丁时同时commit,因此不需要重新commit

  • git am 0001-xxx.patch   // 打单个补丁文件
  • git am filepath/*.patch    // 打某个文件路径下的所有补丁文件

还原补丁:

  • patch –Rp1 < xxx.patch

3.2 git diff 方法

生成标准的patch,只包含diff信息,git diff生成的Patch兼容性强。如果你在修改的代码的版本库不是Git管理的版本库,那么你必须使用git diff生成的patch才能让你的代码被项目的维护人接受。

  • git diff 官方文档:https://git-scm.com/docs/git-diff
  • git apply 官方文档:https://git-scm.com/docs/git-apply

制作补丁:

  • git diff  [pre_commit _id]  [commit_id]  > 【补丁文件名】 // 制作相邻两次commit的补丁
  • git diff  > 【补丁文件名】//  命令没有加任何参数,可制作【当前工作区与上一次commit】的补丁
  • 说明:这里【补丁文件名】是自己定义的,可以是【xxx.patch】也可以是【xxx.diff】,其内容是一致的

打补丁:使用 git apply 命令,这种方法需要重新commit。

  • git apply --stat xxx.patch (xxx.diff)       //  检查补丁文件
  • git apply --check xxx.patch (xxx.diff)   // 检查补丁能否应用成功
  • git apply xxx.patch (xxx.diff)                // 打补丁

还原补丁:

  • patch –Rp1 < xxx.patch

3.3对比分支生成patch

  • git format-patch -M master   // 对当前分支所有超前master的commit生成patch
  • git diff branchName > 【补丁文件名】// 对当前分支与其他分支(branchName)之间的改变生成patch
  • 例:git diff master > patch        // 对当前分支修改与master对比生成patch。
  • 例:git diff new_branch master > patch // 对比new_branch分支与master生成patch。

参考链接:git format-patch以及git的使用

常用分支操作:

  • 查看分支: git branch
  • 创建分支: git branch test_branch  // 创建一个名为test_branch的分支
  • 切换分支: git checkout test_branch 
  • 直接创建分支并切换: git checkout -b test_branch 
  • 删除分支: git branch -D test_branch  
  • 重命名分支: git branch -m test_branch new_test_branch
  • 合并分支:git merge test_branch

3.4 打补丁发生冲突的处理

对于使用git工具制作的补丁,只使用patch命令打补丁也是可以的,但是这种方式略显粗暴。使用git工具打补丁时,其错误检查和信息提示会十分有效,因此用git工具来会打补丁更好。

(1)打补丁时输出提示信息

  • error: xxxxxxx: patch does not apply
    • 出现这种一般会是补丁冲突,可以使用--reject打上补丁,再根据产生的*.rej文件来手动解决冲突。
  • warning: xxxx.c has type 100644, expected 100755
    • 出现这种警告一般是文件内没有冲突,但是文件的权限发生变动。一般没有影响。

(2)打发生补丁冲突的处理

在打入patch发生冲突时,可以执行【git am --skip】跳过此次冲突,也可以执行【git am --abort】回退打入patch的动作,还原到操作前的状态。

还可以使用--reject选项:

即发生冲突时,默认情况下git apply会使整个补丁失效。使用此选项使它应用补丁的适用部分,并将发生冲突的部分放到生成的xxx.rej文件中。

  • git apply --reject xxx.patch

然后 【find ./ -name *.rej 】找到补丁补丁中冲突的部分,根据内容手动修改,解决完冲突后删除后缀为 .rej 的文件。

然后执行【git add.】添加改动到暂存区。(注意,add后有一个点,表示当前路径)。

然后执行【git am --resolved】或者【git am --continue】继续执行被中断的 patch 合入操作。完成后,会有提示信息输出。

可以通过命令 【git  status 】和【 git  log】查看改动过的以及新增的文件,以及确认最终的状态,检查打补丁的效果。

 

4.附Patch命令的详细参数

使用 # man patch 命令查询

  • -b或--backup  备份每一个原始文件。 
  • -B<备份字首字符串>或--prefix=<备份字首字符串>  设置文件备份时,附加在文件名称前面的字首字符串,该字符串可以是路径名称。 
  • -c或--context  把修补数据解译成关联性的差异。 
  • -d<工作目录>或--directory=<工作目录>  设置工作目录。 
  • -D<标示符号>或--ifdef=<标示符号>  用指定的符号把改变的地方标示出来。 
  • -e或--ed 把修补数据解译成ed指令可用的叙述文件。 
  • -E或--remove-empty-files  若修补过后输出的文件其内容是一片空白,则移除该文件。 
  • -f或--force  此参数的效果和指定-t参数类似,但会假设修补数据的版本为新版本。 
  • -F<监别列数>或--fuzz<监别列数>  设置监别列数的最大值。 
  • -g<控制数值>或--get=<控制数值>  设置以RSC或SCCS控制修补作业。 
  • -i<修补文件>或--input=<修补文件>  读取指定的修补问家你。 
  • -l或--ignore-whitespace  忽略修补数据与输入数据的跳格,空格字符。 
  • -n或--normal  把修补数据解译成一般性的差异。 
  • -N或--forward  忽略修补的数据较原始文件的版本更旧,或该版本的修补数据已使用过。 
  • -o<输出文件>或--output=<输出文件>  设置输出文件的名称,修补过的文件会以该名称存放。 
  • -p<剥离层级>或--strip=<剥离层级>  设置欲剥离几层路径名称。 
  • -f<拒绝文件>或--reject-file=<拒绝文件>  设置保存拒绝修补相关信息的文件名称,预设的文件名称为.rej。 
  • -R或--reverse  假设修补数据是由新旧文件交换位置而产生。 
  • -s或--quiet或--silent  不显示指令执行过程,除非发生错误。 
  • -t或--batch  自动略过错误,不询问任何问题。 
  • -T或--set-time  此参数的效果和指定-Z参数类似,但以本地时间为主。 
  • -u或--unified  把修补数据解译成一致化的差异。 
  • -v或--version  显示版本信息。 
  • -V<备份方式>或--version-control=<备份方式>  用-b参数备份目标文件后,备份文件的字尾会被加上一个备份字符串,这个字符串不仅可用-z参数变更,当使用-V参数指定不同备份方式时,也会产生不同字尾的备份字符串。
  • -Y<备份字首字符串>或--basename-prefix=--<备份字首字符串>  设置文件备份时,附加在文件基本名称开头的字首字串。
  • -z<备份字尾字符串>或--suffix=<备份字尾字符串>  此参数的效果和指定-B参数类似,差别在于修补作业使用的路径与文件名若为src/linux/fs/super.c,加上backup/字符串后,文件super.c会备份于/src/linux/fs/backup目录里。 
  • -Z或--set-utc  把修补过的文件更改,存取时间设为UTC。 
  • --backup-if-mismatch  在修补数据不完全吻合,且没有刻意指定要备份文件时,才备份文件。 
  • --binary  以二进制模式读写数据,而不通过标准输出设备。 
  • --help  在线帮助。 
  • --nobackup-if-mismatch  在修补数据不完全吻合,且没有刻意指定要备份文件时,不要备份文件。 
  • --verbose  详细显示指令的执行过程。

 

参考链接:

https://www.jianshu.com/p/ec04de3f95cc

https://www.codesocang.com/jquerymobile/linux/3/18.html

https://www.cnblogs.com/hellokitty2/p/7674237.html

https://www.cnblogs.com/y041039/articles/2411600.html

https://www.cnblogs.com/chenfulin5/p/6210581.html

 


 

你可能感兴趣的:(嵌入式Linux)