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],也沒啥用。

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