Git——功能——patch

  补丁,当本地版本库与远程版本库未直接进行关联,需要通过补丁来进行相关对象的同步(通常是commit)。

  补丁的内容

  git format-patch generates one email message for each selected commit

  git format-patch generates an email message complete with headers that list the commit author, the commit date, and the commit log message associated with the change

     format-patch命令为每次提交都生成一个补丁,补丁的内容头部是邮件的一些信息,和提交相关的信息,包含提交作者,日期,提交的日志信息。内容体,是当前提交与其父提交的比较结果(git diff)。

  补丁的创建,发送,应用。实际工作的应用场景很少。

  官网地址:https://git-scm.com/docs,patching部分和Email部分

1、创建

  使用git format-patch生成补丁。它的选项或者是参数有四种形式,

  1. 第一种形式-n,指最近的n次提交,每次提交都生成一份补丁。
  2. 第二种形式range,在范围之内的提交生成补丁。
  3. 第三种形式是commit的标识,例如引用标识,ID等类似的提交名称
  4. 第四种形式是branch的名称。

  在第二种形式中,若range中存在合并的操作,它生成补丁的步骤如下,

  1. 它会从end开始沿着提交历史找寻所有的父提交,祖父提交直到初始提交。
  2. 之后排除由start开始沿着提交历史找寻到的所有父提交,祖父提交,并且包含start本身。
  3. 最后排除所有合并的提交,也可以理解为有多个父提交的提交。

  假定目前有两个分支alt,master分支,范围为C..F。

  

  

  第一步,从F开始寻找所有父提交,祖父提交,它们包括A,B,C,D,E,F,X,Y,Z。即全部包括

  第二步,排除由C开始寻找到的所有父提交,祖父提交,包含C自身。此时剩余D,E,F,X,Y,Z

  第三步,排除所有合并的提交,即E,此时剩余D,F,X,Y,Z。

  执行git format-patch C..F会为D,F,X,Y,Z每个提交各生成一份补丁。

  第三种形式本质是commitID..HEAD之间的补丁。它与commitID,HEAD有关。执行git format-path master~1与 -1是等价的。

  第四种形式分两种情况,若选项中的分支名称与当前分支名称相同,无任何结果。若分支名称与当前分支名称不同,例如在master分支上执行git format-patch alt,会生成alt分支上没有的,而master分支上存在的提交。

  本质是当前分支与选项分支的差集,并且排除合并的提交。

  格式为:

git format-patch [-k] [(-o|--output-directory) <dir> | --stdout]
                   [--no-thread | --thread[=<style>]]
                   [(--attach|--inline)[=<boundary>] | --no-attach]
                   [-s | --signoff]
                   [--signature=<signature> | --no-signature]
                   [--signature-file=<file>]
                   [-n | --numbered | -N | --no-numbered]
                   [--start-number <n>] [--numbered-files]
                   [--in-reply-to=<message id>] [--suffix=.<sfx>]
                   [--ignore-if-in-upstream]
                   [--cover-from-description=<mode>]
                   [--rfc] [--subject-prefix=<subject prefix>]
                   [(--reroll-count|-v) <n>]
                   [--to=<email>] [--cc=<email>]
                   [--[no-]cover-letter] [--quiet]
                   [--no-notes | --notes[=<ref>]]
                   [--interdiff=<previous>]
                   [--range-diff=<previous> 
                   [--creation-factor=<percent>]]
                   [--progress]
                   [<common diff options>]
                   [ <since> | <revision range>]
        

  它的大部分选项分为三个部分,

  第一部分,补丁文件,例如补丁文件的名称,存放的路径等等。

  第二部分,补丁文件的内容,例如补丁文件的格式。

  第三部分,生成补丁的条件,默认情况下选取提交历史范围,为该范围的每个提交都生成一份补丁文件。

  只需要记住条件和文件的选项。

  文件:

  --no-numbered:文件名中不包含数字。

  --start-number:开始数字,默认值为1,所以生成的补丁文件有0001。

  --numbered-files:文件名称只显示数字。

  --suffix:文件的后缀,默认值为patch,可以设置为txt。

  条件:

  -n,--numbered:最多n个提交。

  --ignore-if-in-upstream:忽略当前提交区间。

  --root:为根提交生成补丁,由于根提交没有父提交,所以通过显示的内容也不是diff结果。

  其他选项略。

2、发送

  使用git send-email发送补丁。本质通过git send-email发送邮件,邮件的内容是补丁文件。

  通过命令行方式发送邮件非常繁琐,它需要大约两部分配置,

  第一部分是服务器相关的,邮件服务器地址,用户名,端口,协议等等。

  第二部分是邮件内容相关的,邮件主题,邮件发送者,接收人,抄送者等等。

  格式为:

git send-email [<options>] <file|directory|rev-list options>…

  邮件相关:

  --from=<address>:发送人

  --to=<address>:收件人

  --bcc=<address>:抄送人

  --cc=<address>:抄送人

  --reply-to=<address>:回复人

  --subject=<string>:邮件的标题

  其他不常见的选项略。

  内容相关:

  --8bit-encoding=<encoding>:略。

  --compose-encoding=<encoding>:略。

  --transfer-encoding=<encoding>:略。

  其他不常见的选项略。

3、应用

  Git应用补丁的指令有两个,apply,am。

  引用apply命令手册的定义:

  Reads the supplied diff output (i.e. "a patch") and applies it to files. When running from a subdirectory in a repository, patched paths outside the directory are ignored. With the --index option the patch is also applied to the index, and with the --cached option the patch is only applied to the index. Without these options, the command applies the patch only to files, and does not require them to be in a Git repository.

  根据当前提交与父提交的比较结果生成补丁文件。在版本库应用补丁时,默认情况下只应用到工作目录,没有对应目录结构的被忽略,添加--index应用到索引,添加--cached只应用到索引。

  This command applies the patch but does not create a commit.

     命令不会产生提交。am命令会产生。

  3.1 apply

  格式为:

git apply [--stat] [--numstat] [--summary] [--check] [--index | --intent-to-add] [--3way]
          [--apply] [--no-add] 
          [--build-fake-ancestor=<file>] [-R | --reverse]
          [--allow-binary-replacement | --binary] [--reject] [-z]
          [-p<n>] [-C<n>] [--inaccurate-eof] [--recount] [--cached]
          [--ignore-space-change | --ignore-whitespace]
          [--whitespace=(nowarn|warn|fix|error|error-all)]
          [--exclude=<path>] [--include=<path>] [--directory=<root>]
          [--verbose] [--unsafe-paths] [<patch>…]

  它只关注应用单个补丁这个过程。

  它的选项分为三类,模拟运行,实际运行,和杂项。

  最常见的是模拟运行和实际运行的选项。

  模拟运行最常见的选项是check,实际运行最常见的选项directory,-3way。

  模拟运行:

  --stat:模拟运行,只显示统计信息

  --numstat:模拟运行,只显示数字统计信息。

  --summary:模拟运行,只显示统计信息中的总结部分

  --check:模拟运行,检查是否存在冲突。

  --index:与模拟运行的选项配合使用,表示会更新index。

  --cached:TODO。

  --intent-to-add:与模拟运行的选项配合使用,表示忽略新增文件类型的修改。

  --apply:与模拟运行的选项配合使用,表示会实际运行。

  实际运行:

  --3way:与am的选项含义相同,冲突发生时,采用合并。

  --reverse:逆序应用补丁。

  --reject: 默认情况下是all or nothing,添加该选项后,只会拒绝失败的补丁,它不会对已经成功的补丁产生影响。

  -p<n>,选取补丁文件路径的后几层级,例如a/b/c/d.patch,-p2之后,补丁的路径变为c/d.patch。感觉没啥用。

  --directory=<root>:指定补丁的根目录。

  --include,--exclude,指定包含哪些,排除哪些,值为补丁文件的路径集合。

  其他:

  -v, verbose公共选项,略。

  --ignore-whitespace, --ignore-space-change, --whitespace=<action>,在am命令中已介绍过。

  --inaccurate-eof:修复文件末尾比较时产生的Bug。

  --recount:不相信原始的行号,重新计算行号,通常不会有人手动修改补丁文件吧。

  --allow-binary-replacement,--binary:TODO。感觉无意义。

  --unsafe-paths:TODO, 感觉无意义。

  --unidiff-zero。

  3.2 am

  格式为:

git am [--signoff] [--keep] [--[no-]keep-cr] [--[no-]utf8]
         [--[no-]3way] 
     [--interactive] [--committer-date-is-author-date]
         [--ignore-date] 
      [--ignore-space-change | --ignore-whitespace]
         [--whitespace=<option>] [-C<n>] [-p<n>] [--directory=<dir>]
         [--exclude=<path>] [--include=<path>] [--reject] 
      [-q | --quiet]
         [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>]
         [(<mbox> | <Maildir>)…]

  am的选项大致可以分为三类。

  第一类是公共选项,例如-q quiet,--interactive, -[no-]utf-8。略。

  第二类是与提交有关的,因为am会创建提交对象。

  第三类是控制整个应用补丁过程的。

  提交信息:

  --signoff:添加签名,或者署名。

  -S[keyid], --gpg-sign=<keyid>:gpg签名

  --[no]message-id:是否将邮件中的messageId添加到commit日志信息中

  --ignore-space-change, --ignore-whitespace, --white-space=<option>:是否忽略空格。

  --committer-date-is-author-date:提交日期使用原始日期。

  --ignore-date:忽略原始日期。

  过程:

  --3,--3way,应用补丁存在冲突时,使用合并策略。

  --skip,跳过当前补丁。

  -r, --resolved,冲突已解决。

  --resolvedmsg=<msg>,冲突解决的日志信息。

  --abort,中断, --quit,退出,--continue,继续。

  其他:

  --patch-format:指定补丁的格式,没什么用

  --show-current-patch=[diff | raw],也没啥用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章