Git
English ▾ 主題 ▾ 最新版本 ▾ git-format-patch 最後更新於 2.46.0

名稱

git-format-patch - 準備電子郵件提交的修補程式

概要

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] [--always]
		   [--cover-from-description=<mode>]
		   [--rfc[=<rfc>]] [--subject-prefix=<subject-prefix>]
		   [(--reroll-count|-v) <n>]
		   [--to=<email>] [--cc=<email>]
		   [--[no-]cover-letter] [--quiet]
		   [--[no-]encode-email-headers]
		   [--no-notes | --notes[=<ref>]]
		   [--interdiff=<previous>]
		   [--range-diff=<previous> [--creation-factor=<percent>]]
		   [--filename-max-length=<n>]
		   [--progress]
		   [<common-diff-options>]
		   [ <since> | <revision-range> ]

描述

為每個非合併提交準備一個「修補程式」,每個提交一個「訊息」,格式化為類似 UNIX 信箱。此命令的輸出對於電子郵件提交或與 git am 一起使用很方便。

此命令產生的「訊息」由三個部分組成

  • 一個簡短的中繼資料標頭,以 From <commit> 開頭,並帶有一個固定的 Mon Sep 17 00:00:00 2001 日期戳記,以幫助像「file(1)」這樣的程式識別該檔案是此命令的輸出,記錄作者身分、作者日期和變更標題(取自提交日誌訊息的第一段)的欄位。

  • 提交日誌訊息的第二段和後續段落。

  • 「修補程式」,即提交與其父系之間的「diff -p --stat」輸出(請參閱 git-diff[1])。

日誌訊息和修補程式以一條三短線分隔。

有兩種方法可以指定要操作的提交。

  1. 單個提交 <since> 指定輸出當前分支尖端中,但不在導向 <since> 的歷史記錄中的提交。

  2. 通用的 <revision-range> 表達式(請參閱 gitrevisions[7] 中的「指定修訂版本」一節)表示指定範圍內的提交。

在單個 <commit> 的情況下,第一條規則優先。要應用第二條規則,即格式化從歷史記錄開始到 <commit> 為止的所有內容,請使用 --root 選項:git format-patch --root <commit>。如果您只想格式化 <commit> 本身,可以使用 git format-patch -1 <commit> 來實現。

預設情況下,每個輸出檔案從 1 開始依序編號,並使用提交訊息的第一行(經過路徑名稱安全處理)作為檔名。使用 --numbered-files 選項,輸出檔案名稱將僅為數字,而不附加提交的第一行。除非指定了 --stdout 選項,否則輸出檔案的名稱會列印到標準輸出。

如果指定 -o,則會在 <dir> 中建立輸出檔案。否則,它們會在目前的工作目錄中建立。可以使用 format.outputDirectory 組態選項設定預設路徑。-o 選項優先於 format.outputDirectory。即使 format.outputDirectory 指向其他位置,仍要在目前的工作目錄中儲存修補程式,請使用 -o .。將會建立所有目錄元件。

預設情況下,單個修補程式的主旨是「[PATCH] 」後接提交訊息中的行,直到第一個空白行為止(請參閱 git-commit[1] 的討論部分)。

當輸出多個修補程式時,主旨前綴會改為「[PATCH n/m] 」。若要強制為單個修補程式新增 1/1,請使用 -n。若要從主旨中省略修補程式編號,請使用 -N

如果給定 --thread,則 git-format-patch 會產生 In-Reply-ToReferences 標頭,使第二封和後續的修補程式郵件顯示為第一封郵件的回覆;這也會產生一個 Message-ID 標頭以供參考。

選項

-p
--no-stat

產生不含任何 diffstat 的純修補程式。

-U<n>
--unified=<n>

產生具有 <n> 行內容的 diff,而不是通常的三行。

--output=<file>

輸出到特定檔案,而不是標準輸出。

--output-indicator-new=<char>
--output-indicator-old=<char>
--output-indicator-context=<char>

指定用於指示產生修補程式中新行、舊行或內容行的字元。通常分別為 +- 和 ' '。

--indent-heuristic

啟用移動 diff 區塊邊界的啟發法,以使修補程式更容易閱讀。這是預設值。

--no-indent-heuristic

停用縮排啟發法。

--minimal

花費額外的時間以確保產生最小的 diff。

--patience

使用「patience diff」演算法產生 diff。

--histogram

使用「histogram diff」演算法產生 diff。

--anchored=<text>

使用「anchored diff」演算法產生 diff。

此選項可以指定多次。

如果有一行同時存在於來源和目的地,僅存在一次,並且以此文字開頭,則此演算法會嘗試防止它在輸出中顯示為刪除或新增。它在內部使用「patience diff」演算法。

--diff-algorithm={patience|minimal|histogram|myers}

選擇 diff 演算法。變體如下

defaultmyers

基本貪婪 diff 演算法。目前,這是預設值。

minimal

花費額外的時間以確保產生最小的 diff。

patience

產生修補程式時使用「patience diff」演算法。

histogram

此演算法將 patience 演算法擴展為「支援低頻率的常見元素」。

例如,如果您將 diff.algorithm 變數設定為非預設值,並且想要使用預設值,則必須使用 --diff-algorithm=default 選項。

--stat[=<width>[,<name-width>[,<count>]]]

產生 diffstat。預設情況下,會盡可能使用多餘的空間來顯示檔名部分,其餘的用於圖形部分。最大寬度預設為終端機寬度,如果未連接到終端機,則預設為 80 欄,並且可以由 <width> 覆寫。檔名部分的寬度可以透過在逗號後給出另一個寬度 <name-width> 或設定 diff.statNameWidth=<width> 來限制。圖形部分的寬度可以使用 --stat-graph-width=<width> 或設定 diff.statGraphWidth=<width> 來限制。使用 --stat--stat-graph-width 會影響產生統計圖的所有命令,而設定 diff.statNameWidthdiff.statGraphWidth 不會影響 git format-patch。透過給出第三個參數 <count>,您可以將輸出限制為前 <count> 行,如果還有更多行,則會加上 ...

這些參數也可以使用 --stat-width=<width>--stat-name-width=<name-width>--stat-count=<count> 單獨設定。

--compact-summary

在 diffstat 中輸出擴充標頭資訊的簡明摘要,例如檔案建立或刪除(「new」或「gone」,如果它是符號連結,則選擇性地加上「+l」)和模式變更(「+x」或「-x」分別表示新增或移除可執行位)。資訊會放在檔名部分和圖形部分之間。暗示 --stat

--numstat

類似於 --stat,但以十進位表示法顯示新增和刪除的行數,以及沒有縮寫的路徑名稱,使其更適合機器讀取。對於二進位檔案,會輸出兩個 -,而不是顯示 0 0

--shortstat

僅輸出 --stat 格式的最後一行,其中包含修改檔案的總數,以及新增和刪除的行數。

-X[<param1,param2,…​>]
--dirstat[=<param1,param2,…​>]

輸出每個子目錄變更相對量的分佈。--dirstat 的行為可以透過傳遞逗號分隔的參數列表進行自訂。預設值由 diff.dirstat 組態變數控制(請參閱git-config[1])。以下參數可用:

changes

透過計算從來源中移除或新增至目的地的行數來計算 dirstat 數字。這會忽略檔案內純程式碼移動的量。換句話說,重新排列檔案中的行不會像其他變更那樣被計入。這是未指定任何參數時的預設行為。

lines

透過執行常規的基於行的 diff 分析並總結已移除/新增的行數來計算 dirstat 數字。(對於二進位檔案,則計算 64 位元組的區塊,因為二進位檔案沒有自然的行概念)。這是一種比 changes 行為更昂貴的 --dirstat 行為,但它會將檔案內重新排列的行視為與其他變更一樣重要。產生的輸出與您從其他 --*stat 選項獲得的結果一致。

files

透過計算已變更的檔案數量來計算 dirstat 數字。每個變更的檔案在 dirstat 分析中都計數相等。這是計算上最便宜的 --dirstat 行為,因為它根本不需要查看檔案內容。

cumulative

同時計算父目錄中子目錄的變更。請注意,當使用 cumulative 時,報告的百分比總和可能超過 100%。預設(非累計)行為可以使用 noncumulative 參數指定。

<limit>

整數參數指定一個截止百分比(預設為 3%)。貢獻低於此百分比變更的目錄不會顯示在輸出中。

範例:以下程式碼將計算已變更的檔案,同時忽略變更檔案總量少於 10% 的目錄,並在父目錄中累積子目錄計數:--dirstat=files,10,cumulative

--cumulative

與 --dirstat=cumulative 的同義詞

--dirstat-by-file[=<param1,param2>…​]

與 --dirstat=files,<param1>,<param2>…​ 的同義詞

--summary

輸出擴充標頭資訊的簡短摘要,例如建立、重新命名和模式變更。

--no-renames

關閉重新命名偵測,即使組態檔預設為啟用。

--[no-]rename-empty

是否使用空 blob 作為重新命名來源。

--full-index

當產生 patch 格式輸出時,在「index」行上顯示完整的 pre- 和 post-image blob 物件名稱,而不是顯示前幾個字元。

--binary

除了 --full-index 之外,還會輸出可以使用 git-apply 套用的二進位 diff。

--abbrev[=<n>]

在 diff-raw 格式輸出和 diff-tree 標頭行中,顯示至少 <n> 個十六進位數字長度的最短字首,該字首唯一引用物件,而不是顯示完整的 40 位元組十六進位物件名稱。在 diff-patch 輸出格式中,--full-index 的優先順序較高,也就是說,如果指定了 --full-index,則將顯示完整的 blob 名稱,而不管 --abbrev 如何。可以使用 --abbrev=<n> 指定非預設的位數。

-B[<n>][/<m>]
--break-rewrites[=[<n>][/<m>]]

將完整的重寫變更分成刪除和建立的配對。這有兩個目的

它會影響檔案的完整重寫變更的方式,不會將其視為一系列刪除和插入混合在一起,並且只有極少數與文字相符的行作為上下文,而是視為單次刪除所有舊內容,然後單次插入所有新內容,而數字 m 控制 -B 選項的此方面(預設為 60%)。-B/70% 指定原始內容的保留比例應少於 30%,Git 才會將其視為完整重寫(也就是說,否則產生的 patch 將是一系列刪除和插入與上下文行混合在一起)。

當與 -M 一起使用時,完全重寫的檔案也會被視為重新命名的來源(通常 -M 只會將消失的檔案視為重新命名的來源),而數字 n 控制 -B 選項的此方面(預設為 50%)。-B20% 指定相較於檔案大小的 20% 或更多的增加和刪除變更,有資格被視為可能重新命名為另一個檔案的來源。

-M[<n>]
--find-renames[=<n>]

偵測重新命名。如果指定了 n,則它是相似度索引的臨界值(即相較於檔案大小的增加/刪除量)。例如,-M90% 表示如果超過 90% 的檔案沒有變更,Git 應該將刪除/新增配對視為重新命名。如果沒有 % 符號,則該數字應讀作一個小數點之前的分數。也就是說,-M5 會變成 0.5,因此與 -M50% 相同。類似地,-M05-M5% 相同。若要限制偵測為精確重新命名,請使用 -M100%。預設相似度索引為 50%。

-C[<n>]
--find-copies[=<n>]

同時偵測複製和重新命名。另請參閱 --find-copies-harder。如果指定了 n,則其含義與 -M<n> 相同。

--find-copies-harder

出於效能考量,預設情況下,只有在複製的原始檔案在同一個變更集中修改時,-C 選項才會尋找複製。此標誌會讓命令檢查未修改的檔案,作為複製來源的候選者。對於大型專案而言,這是一個非常耗費資源的操作,因此請謹慎使用。提供一個以上的 -C 選項具有相同的效果。

-D
--irreversible-delete

省略刪除的 pre-image,也就是說,只列印標頭,而不列印 pre-image 和 /dev/null 之間的差異。產生的 patch 並不適合使用 patchgit apply 套用;這僅適用於只想專注於在變更後檢閱文字的人員。此外,顯然輸出缺乏足夠的資訊,即使是手動也無法反向套用此類 patch,因此使用了此選項的名稱。

-B 一起使用時,也會省略刪除/建立配對中刪除部分的 pre-image。

-l<num>

-M-C 選項涉及一些初步步驟,這些步驟可以便宜地偵測重新命名/複製的子集,然後是詳盡的回退部分,將所有剩餘的未配對目的地與所有相關來源進行比較。(對於重新命名,只有剩餘的未配對來源是相關的;對於複製,所有原始來源都是相關的。)對於 N 個來源和目的地,此詳盡檢查為 O(N^2)。如果涉及的來源/目的地檔案數量超過指定數量,此選項會阻止執行重新命名/複製偵測的詳盡部分。預設為 diff.renameLimit。請注意,值為 0 時會被視為無限。

-O<orderfile>

控制檔案在輸出中出現的順序。這會覆寫 diff.orderFile 組態變數(請參閱git-config[1])。若要取消 diff.orderFile,請使用 -O/dev/null

輸出順序由 <orderfile> 中 glob 模式的順序決定。首先輸出所有路徑名稱與第一個模式相符的檔案,接下來輸出所有路徑名稱與第二個模式相符(但不與第一個模式相符)的檔案,依此類推。最後輸出所有路徑名稱與任何模式都不符的檔案,就像檔案末尾有一個隱式的全部符合模式一樣。如果多個路徑名稱具有相同的排名(它們與相同的模式相符,但與較早的模式不符),它們相對於彼此的輸出順序為正常順序。

<orderfile> 的剖析方式如下:

  • 空白行會被忽略,因此可以用作分隔符以提高可讀性。

  • 以井號 ("#") 開頭的行會被忽略,因此可以用於註解。如果模式以井號開頭,請在模式開頭新增反斜線 ("\")。

  • 每個其他行都包含單個模式。

模式具有與用於 fnmatch(3) 的模式相同的語法和語義,但不含 FNM_PATHNAME 標誌,除非刪除任意數量的最終路徑名稱組件與模式相符,否則路徑名稱也會與模式相符。例如,模式 "foo*bar" 符合 "fooasdfbar" 和 "foo/bar/baz/asdf",但不符合 "foobarx"。

--skip-to=<file>
--rotate-to=<file>

從輸出中捨棄指定 <file> 前的檔案(即跳到),或將其移至輸出的末尾(即旋轉到)。這些選項主要是為了 git difftool 命令而發明的,否則可能不太有用。

--relative[=<path>]
--no-relative

當從專案的子目錄執行時,可以使用此選項來排除目錄外的變更,並顯示相對於該目錄的路徑名稱。當您不在子目錄中(例如,在裸倉庫中)時,您可以透過提供 <path> 作為引數,來指定要將輸出相對於哪個子目錄。--no-relative 可以用來撤銷 diff.relative 配置選項和先前的 --relative

-a
--text

將所有檔案視為文字。

--ignore-cr-at-eol

在進行比較時,忽略行尾的回車符。

--ignore-space-at-eol

忽略行尾空白的變更。

-b
--ignore-space-change

忽略空白數量的變更。這會忽略行尾的空白,並將所有其他一個或多個空白字元的序列視為等效。

-w
--ignore-all-space

比較行時忽略空白。即使一行有空白而另一行沒有,也會忽略差異。

--ignore-blank-lines

忽略所有行為空白的變更。

-I<regex>
--ignore-matching-lines=<regex>

忽略所有行符合 <regex> 的變更。此選項可以指定多次。

--inter-hunk-context=<lines>

顯示 diff 區塊之間的內容,最多為指定的行數,從而融合彼此接近的區塊。預設為 diff.interHunkContext,如果未設定配置選項,則為 0。

-W
--function-context

針對每個變更顯示整個函數作為上下文行。函數名稱的判斷方式與 git diff 計算 patch 區塊標頭的方式相同(請參閱 gitattributes[5] 中的 *定義自訂區塊標頭*)。

--ext-diff

允許執行外部 diff 輔助程式。如果您使用 gitattributes[5] 設定了外部 diff 驅動程式,則需要在 git-log[1] 和相關命令中使用此選項。

--no-ext-diff

不允許使用外部 diff 驅動程式。

--textconv
--no-textconv

允許(或不允許)在比較二進位檔案時執行外部文字轉換篩選器。有關詳細資訊,請參閱 gitattributes[5]。由於 textconv 篩選器通常是單向轉換,因此產生的 diff 適合人類閱讀,但無法套用。因此,textconv 篩選器預設僅在 git-diff[1]git-log[1] 中啟用,而不適用於 git-format-patch[1] 或 diff 底層命令。

--ignore-submodules[=<when>]

忽略 diff 產生中子模組的變更。 <when> 可以是 "none"、"untracked"、"dirty" 或 "all",預設為 "all"。使用 "none" 時,當子模組包含未追蹤或修改的檔案,或其 HEAD 與超專案中記錄的提交不同時,會將子模組視為已修改,並且可以用來覆寫 git-config[1]gitmodules[5] 中 *ignore* 選項的任何設定。當使用 "untracked" 時,僅包含未追蹤內容的子模組不會被視為髒的(但仍會掃描是否有修改的內容)。使用 "dirty" 會忽略子模組工作樹的所有變更,僅顯示超專案中儲存的提交變更(這是 1.7.0 版之前的行為)。使用 "all" 會隱藏子模組的所有變更。

--src-prefix=<prefix>

顯示給定的來源前綴,而不是 "a/"。

--dst-prefix=<prefix>

顯示給定的目標前綴,而不是 "b/"。

--no-prefix

不顯示任何來源或目標前綴。

--default-prefix

使用預設的來源和目標前綴 ("a/" 和 "b/")。這會覆寫配置變數,例如 diff.noprefixdiff.srcPrefixdiff.dstPrefixdiff.mnemonicPrefix(請參閱 git-config(1))。

--line-prefix=<prefix>

在每行輸出前面加上額外的前綴。

--ita-invisible-in-index

預設情況下,使用 "git add -N" 新增的條目會在 "git diff" 中顯示為現有的空檔案,在 "git diff --cached" 中顯示為新檔案。此選項會使條目在 "git diff" 中顯示為新檔案,在 "git diff --cached" 中顯示為不存在。可以使用 --ita-visible-in-index 還原此選項。這兩個選項都是實驗性的,將來可能會被移除。

有關這些常見選項的更詳細說明,另請參閱 gitdiffcore[7]

-<n>

從最上面的 <n> 個提交準備 patch。

-o <dir>
--output-directory <dir>

使用 <dir> 來儲存產生的檔案,而不是目前的工作目錄。

-n
--numbered

即使只有一個 patch,也以 *[PATCH n/m]* 格式命名輸出。

-N
--no-numbered

以 *[PATCH]* 格式命名輸出。

--start-number <n>

從 <n> 開始為 patch 編號,而不是從 1 開始。

--numbered-files

輸出檔案名稱將是一個簡單的數字序列,而不附加預設的提交第一行。

-k
--keep-subject

不要從提交日誌訊息的第一行中移除/新增 *[PATCH]*。

-s
--signoff

使用您自己的提交者身分,將 Signed-off-by 尾部新增至提交訊息。有關詳細資訊,請參閱 git-commit[1] 中的簽署選項。

--stdout

以 mbox 格式將所有提交列印到標準輸出,而不是為每個提交建立檔案。

--attach[=<boundary>]

建立 multipart/mixed 附件,第一部分是提交訊息,第二部分是 patch 本身,並帶有 Content-Disposition: attachment

--no-attach

停用附件的建立,覆寫配置設定。

--inline[=<boundary>]

建立 multipart/mixed 附件,第一部分是提交訊息,第二部分是 patch 本身,並帶有 Content-Disposition: inline

--thread[=<style>]
--no-thread

控制是否新增 In-Reply-ToReferences 標頭,使第二封和後續郵件顯示為第一封郵件的回覆。還控制 Message-ID 標頭的產生,以進行參考。

可選的 <style> 引數可以是 shallowdeep。 *shallow* 線程使每封郵件都回覆到系列的頭部,頭部按封面信、--in-reply-to 和第一封 patch 郵件的順序選擇。 *deep* 線程使每封郵件都回覆到前一封郵件。

預設值為 --no-thread,除非設定了 format.thread 配置。不帶引數的 --thread 等同於 --thread=shallow

請注意,git send-email 的預設值是自行對電子郵件進行線程化。如果您希望 git format-patch 處理線程化,則需要確保為 git send-email 停用線程化。

--in-reply-to=<message-id>

使第一封郵件(或所有使用 --no-thread 的郵件)顯示為回覆給定的 <message-id>,這可以避免中斷線程以提供新的 patch 系列。

--ignore-if-in-upstream

不包含符合 <until>..<since> 中提交的 patch。這將檢查所有可從 <since> 訪問但無法從 <until> 訪問的 patch,並將其與正在產生的 patch 進行比較,任何符合的 patch 都會被忽略。

--always

包含未引入任何變更的提交的 patch,這些提交預設會被省略。

--cover-from-description=<mode>

控制封面信的哪些部分會自動使用分支的描述來填寫。

如果 <mode>messagedefault,則封面信的主旨將使用佔位符文字填寫。封面信的本文將使用分支的描述填寫。這是未指定任何配置或命令列選項時的預設模式。

如果 <mode>subject,則分支描述的第一段將填寫封面信的主旨。其餘的描述將填寫封面信的本文。

如果 <mode>auto,如果分支描述的第一段大於 100 個位元組,則模式將為 message,否則將使用 subject

如果 <mode>none,則封面信的主旨和內文都將會以預留位置的文字填充。

--description-file=<檔案>

使用 <檔案> 的內容,而不是分支的描述來產生封面信。

--subject-prefix=<主旨前綴>

在主旨行中使用 [<主旨前綴>],而不是標準的 [PATCH] 前綴。這可以用來命名一個補丁系列,並且可以與 --numbered 選項結合使用。

設定變數 format.subjectPrefix 也可以用來設定一個主旨前綴,以便套用至給定儲存庫的所有補丁。這在接收多個儲存庫補丁的郵件列表上通常很有用,並且可以用來區分這些補丁(例如,使用 "PATCH my-project" 的值)。

--filename-max-length=<n>

不要使用標準的 64 個位元組,而是在大約 <n> 個位元組處截斷產生的輸出檔案名稱(過短的值會被靜默地提高到合理的長度)。預設為 format.filenameMaxLength 設定變數的值,如果未設定則預設為 64。

--rfc[=<rfc>]

將字串 <rfc>(預設為 "RFC")附加到主旨前綴。由於主旨前綴預設為 "PATCH",因此您預設會得到 "RFC PATCH"。

RFC 表示「徵求意見稿」(Request For Comments);當您發送實驗性補丁以供討論而非應用時,請使用此選項。"--rfc=WIP" 也可能是表示補丁尚未完成的有用方法("WIP" 代表「進行中工作」)。

如果接收社群對於特定額外字串的慣例是在主旨前綴之後加入,則可以在字串 <rfc> 前加上破折號 ("-"),以表示 <rfc> 字串的其餘部分應附加到主旨前綴,例如,--rfc='-(WIP)' 會產生 "PATCH (WIP)"。

-v <n>
--reroll-count=<n>

將該系列標記為該主題的第 <n> 次迭代。輸出檔案名稱會在其前面加上 v<n>,而主旨前綴(預設為 "PATCH",但可透過 --subject-prefix 選項設定)則會在其後附加 ` v<n>`。例如,--reroll-count=4 可能會產生 v4-0001-add-makefile.patch 檔案,其中包含「Subject: [PATCH v4 1/20] Add makefile」。<n> 不必是整數(例如,允許使用 "--reroll-count=4.4" 或 "--reroll-count=4rev2"),但是使用此類重捲計數的缺點是,與先前版本的範圍差異/相互差異不會確切說明新迭代是與哪個版本比較的。

--to=<電子郵件>

在電子郵件標頭中新增 To: 標頭。這是對任何已設定標頭的補充,並且可以多次使用。否定形式 --no-to 會捨棄到目前為止新增的所有 To: 標頭(來自設定檔或命令列)。

--cc=<電子郵件>

在電子郵件標頭中新增 Cc: 標頭。這是對任何已設定標頭的補充,並且可以多次使用。否定形式 --no-cc 會捨棄到目前為止新增的所有 Cc: 標頭(來自設定檔或命令列)。

--from
--from=<身分>

在每個提交電子郵件的 From: 標頭中使用 ident。如果提交的作者身分與提供的 ident 在文字上不相同,則在訊息的主體中放置一個 From: 標頭,其中包含原始作者。如果未提供 ident,則使用提交者身分。

請注意,只有在您實際發送電子郵件並希望將自己識別為寄件者,但保留原始作者時,此選項才有用(而 git am 會正確地擷取主體內的標頭)。另請注意,git send-email 已經為您處理此轉換,如果您將結果傳送到 git send-email,則不應使用此選項。

--[no-]force-in-body-from

透過 --from 選項指定的電子郵件寄件者,預設情況下,如果寄件者與作者不同,則會在提交記錄訊息的頂部新增主體內的「From:」,以識別提交的真實作者。使用此選項,即使寄件者和作者具有相同的名稱和地址,也會新增主體內的「From:」,這有助於解決郵件列表軟體竄改寄件者身分的情況。預設為 format.forceInBodyFrom 設定變數的值。

--add-header=<標頭>

在電子郵件標頭中新增任意標頭。這是對任何已設定標頭的補充,並且可以多次使用。例如,--add-header="Organization: git-foo"。否定形式 --no-add-header 會捨棄到目前為止從設定檔或命令列新增的**所有**(To:Cc: 和自訂)標頭。

--[no-]cover-letter

除了補丁之外,還會產生一個封面信檔案,其中包含分支描述、簡短日誌和整體差異統計。您可以在發送之前在檔案中填寫描述。

--encode-email-headers
--no-encode-email-headers

使用 "Q-encoding"(RFC 2047 中描述)對具有非 ASCII 字元的電子郵件標頭進行編碼,而不是逐字輸出標頭。預設為 format.encodeEmailHeaders 設定變數的值。

--interdiff=<先前>

作為審閱者的輔助工具,在封面信中插入相互差異,或作為 1 個補丁系列的單一補丁的註解,顯示先前版本的補丁系列與目前正在格式化的系列之間的差異。previous 是一個單一修訂版本,命名先前系列的頂端,該系列與目前正在格式化的系列共享一個共同的基準(例如,git format-patch --cover-letter --interdiff=feature/v1 -3 feature/v2)。

--range-diff=<先前>

作為審閱者的輔助工具,在封面信中插入範圍差異(請參閱 git-range-diff[1]),或作為 1 個補丁系列的單一補丁的註解,顯示先前版本的補丁系列與目前正在格式化的系列之間的差異。如果 previous 與目前正在格式化的系列共享一個共同的基準,則它可以是一個單一修訂版本,命名先前系列的頂端(例如,git format-patch --cover-letter --range-diff=feature/v1 -3 feature/v2),或者如果該系列的兩個版本不相交,則可以是一個修訂版本範圍(例如,git format-patch --cover-letter --range-diff=feature/v1~3..feature/v1 -3 feature/v2)。

請注意,傳遞給命令的差異選項會影響 format-patch 的主要產品的產生方式,並且它們不會傳遞給用於產生封面信內容的基礎 range-diff 機制(這將來可能會變更)。

--creation-factor=<百分比>

--range-diff 一起使用時,透過調整建立/刪除成本調整係數來調整在先前和目前補丁系列之間比對提交的啟發式演算法。有關詳細資料,請參閱 git-range-diff[1])。

預設值為 999(git-range-diff[1] 使用 60),因為使用案例是要顯示與同一主題的較舊迭代的比較,並且該工具應在兩組補丁之間找到更多對應關係。

--notes[=<參照>]
--no-notes

在三條虛線之後附加提交的註解(請參閱 git-notes[1])。

此選項的預期使用案例是為不屬於提交記錄訊息本身的提交撰寫支援說明,並將其包含在補丁提交中。雖然可以在 format-patch 執行後但在發送之前簡單地撰寫這些說明,但將它們保留為 Git 註解可以讓它們在補丁系列的版本之間保持維護(但請參閱 git-notes[1] 中關於 notes.rewrite 設定選項的討論以使用此工作流程)。

預設值為 --no-notes,除非設定了 format.notes 設定。

--[no-]signature=<簽名>

將簽名新增至產生的每個訊息。根據 RFC 3676,簽名由一行帶有 '-- ' 的行與主體分隔。如果省略簽名選項,則簽名預設為 Git 版本號碼。

--signature-file=<檔案>

運作方式與 --signature 完全相同,只是簽名是從檔案中讀取的。

--suffix=.<sfx>

不要使用 .patch 作為產生檔案名稱的後綴,而應使用指定的後綴。常見的替代方案是 --suffix=.txt。將此選項留空將會移除 .patch 後綴。

請注意,前導字元不必是點號;例如,您可以使用 --suffix=-patch 來取得 0001-description-of-my-change-patch

-q
--quiet

不要將產生的檔案名稱列印到標準輸出。

--no-binary

不要輸出二進位檔案中變更的內容,而是顯示這些檔案已變更的通知。使用此選項產生的補丁無法正確應用,但它們對於程式碼審查仍然很有用。

--zero-commit

在每個補丁的 From 標頭中輸出全為零的雜湊,而不是提交的雜湊。

--[no-]base[=<提交>]

記錄基準樹狀結構資訊,以識別補丁系列套用的狀態。有關詳細資料,請參閱下面的「基準樹狀結構資訊」章節。如果 <提交> 為「auto」,則會自動選擇基準提交。--no-base 選項會覆寫 format.useAutoBase 設定。

--root

將修訂版本引數視為 <修訂版本範圍>,即使它只是一個單一提交(通常會被視為 <起始版本>)。請注意,指定範圍中包含的根提交始終格式化為建立補丁,而與此標誌無關。

--progress

在產生補丁時,在 stderr 上顯示進度報告。

設定

您可以指定要新增至每個訊息的其他郵件標頭行、主旨前綴和檔案後綴的預設值、在輸出多個補丁時對補丁編號、新增 "To:" 或 "Cc:" 標頭、設定附件、變更補丁輸出目錄,以及使用設定變數對補丁進行簽署。

[format]
	headers = "Organization: git-foo\n"
	subjectPrefix = CHANGE
	suffix = .txt
	numbered = auto
	to = <email>
	cc = <email>
	attach [ = mime-boundary-string ]
	signOff = true
	outputDirectory = <directory>
	coverLetter = auto
	coverFromDescription = auto

討論

git format-patch 產生的補丁採用 UNIX 郵箱格式,其中包含固定的「魔術」時間戳記,以表示該檔案是從 format-patch 輸出,而不是真實的郵箱,如下所示

From 8f72bad1baf19a53459661343e21d6491c3908d3 Mon Sep 17 00:00:00 2001
From: Tony Luck <tony.luck@intel.com>
Date: Tue, 13 Jul 2010 11:42:54 -0700
Subject: [PATCH] =?UTF-8?q?[IA64]=20Put=20ia64=20config=20files=20on=20the=20?=
 =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig=20diet?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

arch/arm config files were slimmed down using a python script
(See commit c2330e286f68f1c408b4aa6515ba49d57f05beae comment)

Do the same for ia64 so we can have sleek & trim looking
...

通常,它會放置在 MUA 的草稿資料夾中,經過編輯以在三條虛線後新增不應進入變更記錄的及時註解,然後作為一個訊息發送,在我們的範例中,該訊息的主體以「arch/arm config files were…​」開頭。在接收端,讀者可以將感興趣的補丁儲存在 UNIX 郵箱中,並使用 git-am[1] 應用它們。

當一個 patch 是正在進行的討論的一部分時,由 git format-patch 產生的 patch 可以進行調整,以利用 git am --scissors 功能。在您對討論的回應之後,會有一行只包含 "-- >8 --"(剪刀和穿孔線),然後是已移除不必要標頭欄位的 patch。

...
> So we should do such-and-such.

Makes sense to me.  How about this patch?

-- >8 --
Subject: [IA64] Put ia64 config files on the Uwe Kleine-König diet

arch/arm config files were slimmed down using a python script
...

當以這種方式傳送 patch 時,最常見的情況是您傳送自己的 patch,因此除了 "From $SHA1 $magic_timestamp" 標記之外,您還應該從 patch 檔案中省略 From:Date: 行。patch 的標題可能與 patch 回應的討論主題不同,因此您可能會想保留 Subject: 行,如上面的範例所示。

檢查 patch 是否損壞

許多郵件程式如果未正確設定,會損壞空白字元。以下是兩種常見的損壞類型:

  • 不包含任何空白字元的空白上下文行。

  • 在開頭有一個額外空白字元的非空白上下文行。

測試您的 MUA 是否設定正確的方法之一是:

  • 以您通常的方式將 patch 寄給自己,除了 To: 和 Cc: 行不包含列表和維護者地址之外。

  • 將該 patch 以 UNIX 郵件信箱格式儲存到檔案中。假設將其命名為 a.patch。

  • 套用它:

    $ git fetch <project> master:test-apply
    $ git switch test-apply
    $ git restore --source=HEAD --staged --worktree :/
    $ git am a.patch

如果它沒有正確套用,可能有多種原因。

  • patch 本身無法乾淨地套用。這很糟糕,但與您的 MUA 沒有太大關係。在這種情況下,您可能需要使用 git-rebase[1] 重新基底 patch,然後再重新產生它。

  • MUA 損壞了您的 patch; "am" 會抱怨 patch 無法套用。查看 .git/rebase-apply/ 子目錄,查看patch 檔案包含什麼,並檢查上面提到的常見損壞模式。

  • 同時,也檢查 infofinal-commit 檔案。如果 final-commit 中的內容與您希望在提交日誌訊息中看到的內容不完全相同,則接收者很可能會在套用您的 patch 時手動編輯日誌訊息。patch 電子郵件中的 "Hi, this is my first patch.\n" 之類的內容應在表示提交訊息結尾的三個破折號之後。

MUA 特定提示

以下是一些關於如何使用各種郵件程式成功內嵌提交 patch 的提示。

GMail

GMail 在網頁介面中沒有任何關閉換行的方式,因此它會損壞您傳送的任何電子郵件。但是,您可以使用 "git send-email" 並透過 GMail SMTP 伺服器傳送您的 patch,或使用任何 IMAP 電子郵件用戶端連線到 Google IMAP 伺服器並透過它轉寄電子郵件。

有關使用 git send-email 透過 GMail SMTP 伺服器傳送您的 patch 的提示,請參閱 git-send-email[1] 的範例部分。

有關使用 IMAP 介面提交的提示,請參閱 git-imap-send[1] 的範例部分。

Thunderbird

預設情況下,Thunderbird 會同時包裝電子郵件並將其標記為 format=flowed,這兩者都會使 Git 無法使用產生的電子郵件。

有三種不同的方法:使用附加元件關閉換行、設定 Thunderbird 不要損壞 patch,或使用外部編輯器來防止 Thunderbird 損壞 patch。

方法一(附加元件)

安裝可從 https://addons.mozilla.org/thunderbird/addon/toggle-word-wrap/ 取得的「切換文字換行」附加元件。它會在撰寫器的「選項」選單中新增一個選單項目「啟用文字換行」,您可以取消勾選。現在您可以像往常一樣撰寫訊息(剪下 + 貼上、git format-patch | git imap-send 等),但您必須在您輸入的任何文字中手動插入換行符號。

方法二(設定)

三個步驟:

  1. 將您的郵件伺服器撰寫設定為純文字:編輯...帳號設定...撰寫和地址,取消勾選「以 HTML 撰寫訊息」。

  2. 將您的通用撰寫視窗設定為不換行。

    在 Thunderbird 2 中:編輯..偏好設定..撰寫,在 0 處包裝純文字訊息

    在 Thunderbird 3 中:編輯..偏好設定..進階..設定編輯器。搜尋 "mail.wrap_long_lines"。切換它以確保設定為 false。此外,搜尋 "mailnews.wraplength" 並將值設定為 0。

  3. 停用 format=flowed 的使用:編輯..偏好設定..進階..設定編輯器。搜尋 "mailnews.send_plaintext_flowed"。切換它以確保設定為 false

完成之後,您應該能夠像往常一樣撰寫電子郵件(剪下 + 貼上、git format-patch | git imap-send 等),並且 patch 不會被損壞。

方法三(外部編輯器)

需要以下 Thunderbird 擴充功能:來自 https://mjg.github.io/AboutConfig/ 的 AboutConfig 和來自 https://globs.org/articles.php?lng=en&pg=8 的外部編輯器

  1. 使用您選擇的方法將 patch 準備為文字檔案。

  2. 在開啟撰寫視窗之前,請使用「編輯」→「帳號設定」取消勾選要用於傳送 patch 的帳號的「撰寫和地址」面板中的「以 HTML 格式撰寫訊息」設定。

  3. 在主要的 Thunderbird 視窗中,在您開啟 patch 的撰寫視窗之前,請使用「工具」→「about:config」將以下設定為指示的值:

    	mailnews.send_plaintext_flowed  => false
    	mailnews.wraplength             => 0
  4. 開啟撰寫視窗並按一下外部編輯器圖示。

  5. 在外部編輯器視窗中,讀取 patch 檔案並正常退出編輯器。

附註:也許可以使用 about:config 和以下設定來執行步驟 2,但尚未有人嘗試過。

	mail.html_compose                       => false
	mail.identity.default.compose_html      => false
	mail.identity.id?.compose_html          => false

contrib/thunderbird-patch-inline 中有一個腳本,可以幫助您以簡單的方式在 Thunderbird 中包含 patch。若要使用它,請執行上述步驟,然後使用該腳本作為外部編輯器。

KMail

這應該可以幫助您使用 KMail 內嵌提交 patch。

  1. 將 patch 準備為文字檔案。

  2. 按一下「新郵件」。

  3. 在撰寫器視窗中,前往「選項」,並確保未設定「文字換行」。

  4. 使用「訊息」→「插入檔案...」並插入 patch。

  5. 回到撰寫視窗:將您希望的任何其他文字新增至訊息,填寫地址和主旨欄位,然後按一下「傳送」。

基礎樹狀結構資訊

基礎樹狀結構資訊區塊用於讓維護者或協力廠商測試人員了解 patch 系列套用的確切狀態。它包含基礎提交,這是專案歷史中穩定部分的一個眾所周知的提交,其他人都以此為基礎工作,以及零個或多個必要條件 patch,這些是在基礎提交之上需要套用的正在進行的眾所周知的 patch,它們還不是基礎提交的一部分,並且在套用 patch 之前需要按拓撲順序套用。

基礎提交顯示為 "base-commit: ",後接提交物件名稱的 40 個十六進位字元。必要條件 patch 顯示為 "prerequisite-patch-id: ",後接 40 個十六進位patch ID,可以透過 git patch-id --stable 命令傳遞 patch 來取得。

假設在公用提交 P 之上,您從其他人那裡套用了眾所周知的 patch X、Y 和 Z,然後建立了您的三個 patch 系列 A、B、C,則歷史記錄將如下所示:

---P---X---Y---Z---A---B---C

使用 git format-patch --base=P -3 C(或其變體,例如使用 --cover-letter 或使用 Z..C 而不是 -3 C 來指定範圍),基礎樹狀結構資訊區塊會顯示在命令輸出的第一個訊息(第一個 patch 或封面信)的末尾,如下所示:

base-commit: P
prerequisite-patch-id: X
prerequisite-patch-id: Y
prerequisite-patch-id: Z

對於非線性拓撲,例如:

---P---X---A---M---C
    \         /
     Y---Z---B

您也可以使用 git format-patch --base=P -3 C 為 A、B 和 C 產生 patch,並且 P、X、Y、Z 的識別碼會附加在第一個訊息的末尾。

如果在 cmdline 中設定 --base=auto,它會自動計算基礎提交,作為遠端追蹤分支的尖端提交與 cmdline 中指定修訂範圍的合併基礎。對於本機分支,您需要在使用此選項之前使用 git branch --set-upstream-to 使其追蹤遠端分支。

範例

  • 擷取修訂版本 R1 和 R2 之間的提交,並使用 git am 將它們套用在目前分支之上,以挑選它們。

    $ git format-patch -k --stdout R1..R2 | git am -3 -k
  • 擷取目前分支中但不在 origin 分支中的所有提交。

    $ git format-patch origin

    每個提交都會在目前目錄中建立一個單獨的檔案。

  • 擷取自專案開始以來導致 origin 的所有提交。

    $ git format-patch --root origin
  • 與前一個相同。

    $ git format-patch -M -B origin

    此外,它會智慧地偵測並處理重新命名和完整重寫,以產生重新命名 patch。重新命名 patch 減少了文字輸出量,並且通常更容易審閱。請注意,非 Git 的 "patch" 程式無法理解重新命名 patch,因此只有在您知道接收者使用 Git 套用您的 patch 時才使用它。

  • 從目前分支擷取最上面的三個提交,並將其格式化為可透過電子郵件傳送的 patch。

    $ git format-patch -3

注意事項

請注意,即使合併提交是請求範圍的一部分,format-patch 也會從輸出中省略它們。一個簡單的 "patch" 不包含足夠的資訊,供接收端複製相同的合併提交。

GIT

屬於 git[1] 套件的一部分

scroll-to-top