English ▾ 主题 ▾ 最新版本 ▾ git-format-patch 上次更新于 2.48.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

生成没有任何 diffstats 的纯补丁。

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

生成带有 <n> 行上下文的差异,而不是通常的三行。

--output=<file>

输出到特定文件,而不是 stdout。

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

指定用于指示生成的补丁中的新行,旧行或上下文行的字符。 通常它们分别是 +- 和 ' '。

--indent-heuristic

启用启发式方法,该方法移动差异块边界以使补丁更易于阅读。 这是默认设置。

--no-indent-heuristic

禁用缩进启发式。

--minimal

花费额外的时间以确保产生尽可能小的差异。

--patience

使用“耐心差异”算法生成差异。

--histogram

使用“直方图差异”算法生成差异。

--anchored=<text>

使用“锚定差异”算法生成差异。

可以多次指定此选项。

如果一行存在于源和目标中,仅存在一次,并且以<text>开头,则此算法尝试防止其在输出中显示为删除或添加。 它在内部使用“耐心差异”算法。

--diff-algorithm=(patience|minimal|histogram|myers)

选择差异算法。 变体如下

default
myers

基本贪婪差异算法。 当前,这是默认值。

minimal

花费额外的时间以确保产生尽可能小的差异。

patience

生成补丁时,使用“耐心差异”算法。

histogram

此算法扩展了耐心算法以“支持低发生率的公共元素”。

例如,如果将 diff.algorithm 变量配置为非默认值,并且想要使用默认值,则必须使用 --diff-algorithm=default 选项。

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

生成一个 diffstat。默认情况下,文件名字段将使用尽可能多的空间,其余用于图形部分。最大宽度默认为终端宽度,如果未连接到终端,则为 80 列,并且可以被 <width> 覆盖。文件名部分的宽度可以通过在逗号后给出另一个宽度 <name-width> 或设置 diff.statNameWidth=<name-width> 来限制。图形部分的宽度可以使用 --stat-graph-width=<graph-width> 或设置 diff.statGraphWidth=<graph-width> 来限制。使用 --stat--stat-graph-width 会影响所有生成 stat 图的命令,而设置 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 [<param>,...]
--dirstat[=<param>,...]

输出每个子目录的相对更改量的分布。可以通过传递一个逗号分隔的参数列表来自定义 --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[=<param>,...]

--dirstat=files,<param>,... 的同义词。

--summary

输出扩展头信息的精简摘要,例如创建、重命名和模式更改。

--no-renames

关闭重命名检测,即使配置文件给出了默认设置。

--[no-]rename-empty

是否使用空 blob 作为重命名源。

--full-index

在生成补丁格式输出时,在 “index” 行上显示完整的 pre- 和 post-image blob 对象名称,而不是前几个字符。

--binary

除了 --full-index 之外,还输出一个二进制 diff,可以使用 git-apply 应用。

--abbrev[=<n>]

在 diff-raw 格式输出和 diff-tree 标头行中,显示至少 <n> 个十六进制数字长的最短前缀,该前缀唯一地引用该对象,而不是显示完整的 40 字节十六进制对象名称。 在 diff-patch 输出格式中,--full-index 具有更高的优先级,即如果指定了 --full-index,则无论 --abbrev 如何,都将显示完整的 blob 名称。 可以使用 --abbrev=<n> 指定非默认的位数。

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

将完全重写更改分解为删除和创建对。这有两个目的:

它影响了完全重写文件的方式,不再是将更改视为一系列删除和插入混合在一起,只有极少数行恰好与文本匹配作为上下文,而是将更改视为删除所有旧内容,然后插入所有新内容,数字 <m> 控制 -B 选项的这一方面(默认为 60%)。-B/70% 指定如果原始文件中的保留量小于 30%,则 Git 认为它是完全重写(即,否则生成的补丁将是一系列删除和插入与上下文行混合在一起)。

当与 -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

省略删除的 preimage,即仅打印标头,而不打印 preimage 和 /dev/null 之间的 diff。生成的补丁并不意味着要与 patchgit apply 一起应用; 这仅适用于只想专注于查看更改后的文本的人。此外,输出显然缺乏足够的信息来反向应用此类补丁,即使是手动应用也是如此,因此选项的名称如此。

-B 一起使用时,也省略删除/创建对的删除部分中的 preimage。

-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> 文件之前的文件(即 skip to),或者将它们移动到输出的末尾(即 rotate to)。这些选项主要为 git difftool 命令而设计,否则可能不太有用。

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

当从项目的子目录运行时,可以使用此选项排除目录外的更改,并显示相对于该目录的路径名。当您不在子目录中(例如,在裸仓库中),可以通过提供 <path> 作为参数来指定使输出相对于哪个子目录。可以使用 --no-relative 来抵消 diff.relative 配置选项和之前的 --relative

-a
--text

将所有文件视为文本。

--ignore-cr-at-eol

比较时忽略行尾的回车符。

--ignore-space-at-eol

忽略 EOL 处的空格更改。

-b
--ignore-space-change

忽略空格数量的变化。 这忽略行尾的空格,并将一个或多个空格字符的所有其他序列视为等效。

-w
--ignore-all-space

比较行时忽略空格。 即使一行有空格而另一行没有空格,这也忽略差异。

--ignore-blank-lines

忽略所有行都为空白的更改。

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

忽略所有行都匹配 <regex> 的更改。 可以多次指定此选项。

--inter-hunk-context=<number>

显示 diff hunk 之间的上下文,最多指定的 <number> 行,从而融合彼此接近的 hunk。 默认为 diff.interHunkContext,如果未设置配置选项则为 0。

-W
--function-context

将整个函数显示为每个更改的上下文行。 函数名称的确定方式与 git diff 计算 patch hunk 标头的方式相同(请参阅 gitattributes[5] 中的“Defining a custom hunk-header”)。

--ext-diff

允许执行外部 diff 助手。 如果您使用 gitattributes[5] 设置了外部 diff 驱动程序,则需要将此选项与 git-log[1] 及其同类命令一起使用。

--no-ext-diff

禁止外部 diff 驱动程序。

--textconv
--no-textconv

允许(或禁止)在比较二进制文件时运行外部文本转换过滤器。 有关详细信息,请参见 gitattributes[5]。 因为 textconv 过滤器通常是单向转换,所以生成的 diff 适合人类使用,但不能应用。 因此,默认情况下仅为 git-diff[1]git-log[1] 启用 textconv 过滤器,但不为 git-format-patch[1] 或 diff 管道命令启用。

--ignore-submodules[=(none|untracked|dirty|all)]

忽略 diff 生成中子模块的更改。 all 是默认值。 使用 none 将在子模块包含未跟踪或修改的文件,或者其 HEAD 与超级项目中记录的提交不同时,将其视为已修改,并且可用于覆盖 git-config[1]gitmodules[5]ignore 选项的任何设置。 当使用 untracked 时,如果子模块仅包含未跟踪的内容,则不会将其视为脏的(但仍会扫描修改的内容)。 使用 dirty 会忽略对子模块工作树的所有更改,仅显示对超级项目中存储的提交的更改(这是 1.7.0 之前的行为)。 使用 all 隐藏对子模块的所有更改。

--src-prefix=<prefix>

显示给定的源 <prefix>,而不是 "a/"。

--dst-prefix=<prefix>

显示给定的目标 <prefix>,而不是 "b/"。

--no-prefix

不显示任何源或目标前缀。

--default-prefix

使用默认的源和目标前缀(“a/”和“b/”)。 这将覆盖配置变量,例如 diff.noprefixdiff.srcPrefixdiff.dstPrefixdiff.mnemonicPrefix(请参阅 git-config[1])。

--line-prefix=<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> 个提交准备补丁。

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

使用 <dir> 来存储结果文件,而不是当前工作目录。

-n
--numbered

[PATCH n/m] 格式命名输出,即使只有一个补丁。

-N
--no-numbered

[PATCH] 格式命名输出。

--start-number <n>

从 <n> 而不是 1 开始编号补丁。

--numbered-files

输出文件名将是一个简单的数字序列,不附加提交的默认第一行。

-k
--keep-subject

不要从提交日志消息的第一行删除/添加 [PATCH]

-s
--signoff

使用您自己的提交者身份将 Signed-off-by 尾部添加到提交消息。 有关更多信息,请参见 git-commit[1] 中的 signoff 选项。

--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> 参数可以是 shallowdeepshallow 线程使每封邮件都回复到系列邮件的头部,其中头部按封面信、--in-reply-to 和第一封 patch 邮件的顺序选择。 deep 线程使每封邮件都回复到前一封邮件。

除非设置了 format.thread 配置,否则默认为 --no-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,默认情况下会省略这些 patch。

--cover-from-description=<mode>

控制封面信的哪些部分将使用分支的描述自动填充。

如果 <mode>messagedefault,则封面信的主题将填充占位符文本。 封面信的正文将填充分支的描述。 这是没有指定配置或命令行选项时的默认模式。

如果 <mode>subject,则分支描述的第一段将填充封面信的主题。 描述的其余部分将填充封面信的正文。

如果 <mode>auto,如果分支描述的第一段大于 100 字节,则模式将为 message,否则将使用 subject

如果 <mode>none,则封面信的主题和正文都将填充占位符文本。

--description-file=<file>

使用 <file> 的内容而不是分支的描述来生成封面信。

--subject-prefix=<subject-prefix>

不要使用主题行中的标准 [PATCH] 前缀,而是使用 [<subject-prefix>]。这可用于命名一个补丁系列,并且可以与 --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" 表示 "Work In Progress")。

如果接收社区对于特定额外字符串的约定是将其放在主题前缀之后,则字符串 <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"),但是使用这种重新滚动计数的缺点是,与先前版本的 range-diff/interdiff 没有明确说明新迭代与哪个版本进行了比较。

--to=<email>

To: 标头添加到电子邮件标头。这是对任何已配置标头的补充,并且可以多次使用。否定形式 --no-to 会丢弃到目前为止添加的所有 To: 标头(来自配置或命令行)。

--cc=<email>

Cc: 标头添加到电子邮件标头。这是对任何已配置标头的补充,并且可以多次使用。否定形式 --no-cc 会丢弃到目前为止添加的所有 Cc: 标头(来自配置或命令行)。

--from
--from=<ident>

在每个提交电子邮件的 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=<header>

将任意标头添加到电子邮件标头。这是对任何已配置标头的补充,并且可以多次使用。例如,--add-header="Organization: git-foo"。否定形式 --no-add-header 会丢弃到目前为止从配置或命令行添加的所有To:Cc: 和自定义)标头。

--[no-]cover-letter

除了补丁之外,还生成一个包含分支描述、简短日志和总体 diffstat 的封面信文件。您可以在发送文件之前在文件中填写描述。

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

使用 "Q-encoding"(在 RFC 2047 中描述)对具有非 ASCII 字符的电子邮件标头进行编码,而不是逐字输出标头。默认为 format.encodeEmailHeaders 配置变量的值。

--interdiff=<previous>

作为审查辅助工具,将 interdiff 插入到封面信中,或者作为单补丁系列的单个补丁的注释,显示先前版本的补丁系列与当前格式化的系列之间的差异。previous 是一个修订版,用于命名先前系列的尖端,该系列与当前格式化的系列共享一个公共基础(例如 git format-patch --cover-letter --interdiff=feature/v1 -3 feature/v2)。

--range-diff=<previous>

作为审查辅助工具,将 range-diff(参见 git-range-diff[1])插入到封面信中,或者作为单补丁系列的单个补丁的注释,显示先前版本的补丁系列与当前格式化的系列之间的差异。如果先前系列与当前格式化的系列共享一个公共基础,则 previous 可以是一个修订版,用于命名先前系列的尖端(例如 git format-patch --cover-letter --range-diff=feature/v1 -3 feature/v2),或者如果系列的两个版本不相交,则 previous 可以是一个修订版范围(例如 git format-patch --cover-letter --range-diff=feature/v1~3..feature/v1 -3 feature/v2)。

请注意,传递给命令的 diff 选项会影响 format-patch 的主要产品的生成方式,它们不会传递给用于生成封面信材料的底层 range-diff 机制(将来可能会更改)。

--creation-factor=<percent>

--range-diff 一起使用,通过调整创建/删除成本的微调因子来调整启发式算法,该算法将先前系列和当前系列之间的提交进行匹配。有关详细信息,请参见 git-range-diff[1])。

默认为 999(git-range-diff[1] 使用 60),因为用例是显示与同一主题的旧迭代的比较,并且该工具应该在两组补丁之间找到更多对应关系。

--notes[=<ref>]
--no-notes

在三划线之后附加提交的注释(请参见 git-notes[1])。

此功能的预期用例是为不属于提交日志消息本身的提交编写支持性说明,并将其包含在补丁提交中。虽然可以简单地在 format-patch 运行之后但在发送之前编写这些说明,但将它们保留为 Git 注释可以使它们在补丁系列的各个版本之间保持维护(但请参阅 git-notes[1] 中关于 notes.rewrite 配置选项的讨论,以使用此工作流程)。

除非设置了 format.notes 配置,否则默认为 --no-notes

--[no-]signature=<signature>

向生成的每条消息添加签名。根据 RFC 3676,签名与正文之间用一行 "— " 分隔。如果省略了签名选项,则签名默认为 Git 版本号。

--signature-file=<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[=<commit>]

记录基本树信息以识别补丁系列应用到的状态。有关详细信息,请参见下面的基本树信息部分。如果 <commit> 是 "auto",则会自动选择基本提交。--no-base 选项将覆盖 format.useAutoBase 配置。

--root

将修订参数视为一个 <revision-range>,即使它只是一个单独的提交(通常会被视为一个 <since>)。请注意,指定范围中包含的根提交始终会被格式化为创建补丁,而与此标志无关。

--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 邮箱格式,带有一个固定的 "magic" 时间戳,用于指示该文件是 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] 应用它们。

当补丁是正在进行的讨论的一部分时,可以调整 git format-patch 生成的补丁,以利用 git am --scissors 功能。在您对讨论的回复之后,会有一行仅包含 "-- >8 --"(剪刀和穿孔),然后是删除了不必要的标头字段的补丁

...
> 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
...

以这种方式发送补丁时,最常见的情况是您发送的是自己的补丁,因此除了 "From $SHA1 $magic_timestamp" 标记之外,您还应从补丁文件中省略 From:Date: 行。补丁标题可能与补丁所响应的讨论主题不同,因此您可能希望保留 Subject: 行,如上面的示例所示。

检查补丁是否损坏

如果设置不正确,许多邮件客户端会破坏空格。以下是两种常见的损坏类型

  • 没有任何空格的空上下文行。

  • 在开头有一个额外空格的非空上下文行。

测试 MUA 设置是否正确的一种方法是

  • 以您通常的方式将补丁发送给自己,除了 To: 和 Cc: 行不包含列表和维护者地址。

  • 将该补丁以 UNIX 邮箱格式保存到文件中。假设将其命名为 a.patch。

  • 应用它

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

如果它无法正确应用,则可能有多种原因。

  • 补丁本身无法干净地应用。这是的,但与您的 MUA 关系不大。在这种情况下,您可能希望使用 git-rebase[1] 重新变基补丁,然后再重新生成它。

  • MUA 损坏了您的补丁;"am" 会抱怨补丁无法应用。查看 .git/rebase-apply/ 子目录,查看 patch 文件包含的内容,并检查上面提到的常见损坏模式。

  • 同时,检查 infofinal-commit 文件。如果 final-commit 中的内容与您希望在提交日志消息中看到的内容不完全相同,则很可能接收者在应用您的补丁时最终会手动编辑日志消息。补丁电子邮件中的 "Hi, this is my first patch.\n" 等内容应放在表示提交消息结尾的三个破折号之后。

MUA 特定提示

以下是一些关于如何使用各种邮件客户端成功内联提交补丁的提示。

GMail

GMail 无法关闭 Web 界面中的换行,因此它会破坏您发送的任何电子邮件。但是,您可以使用 "git send-email" 并通过 GMail SMTP 服务器发送您的补丁,或者使用任何 IMAP 电子邮件客户端连接到 google IMAP 服务器并通过它转发电子邮件。

有关使用 git send-email 通过 GMail SMTP 服务器发送补丁的提示,请参阅 git-send-email[1] 的 EXAMPLE 部分。

有关使用 IMAP 界面提交的提示,请参阅 git-imap-send[1] 的 EXAMPLE 部分。

Thunderbird

默认情况下,Thunderbird 会换行电子邮件,并将其标记为 format=flowed,这两种方式都会使生成的电子邮件无法被 Git 使用。

有三种不同的方法:使用附加组件关闭行换行,配置 Thunderbird 不要损坏补丁,或使用外部编辑器来防止 Thunderbird 损坏补丁。

方法 #1(附加组件)

安装 Toggle Word Wrap 附加组件,可从 https://addons.mozilla.org/thunderbird/addon/toggle-word-wrap/ 获取。它在编辑器 "选项" 菜单中添加一个菜单项 "Enable Word Wrap",您可以取消选中它。现在您可以像往常一样撰写邮件(剪切 + 粘贴,git format-patch | git imap-send 等),但您必须在您键入的任何文本中手动插入换行符。

方法 #2(配置)

三个步骤

  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 等),并且补丁不会被损坏。

方法 #3(外部编辑器)

需要以下 Thunderbird 扩展:来自 https://mjg.github.io/AboutConfig/ 的 AboutConfig 和来自 https://globs.org/articles.php?lng=en&pg=8 的 External Editor

  1. 使用您选择的方法将补丁准备为文本文件。

  2. 在打开撰写窗口之前,使用编辑→帐户设置取消选中要用于发送补丁的帐户的 "撰写和寻址" 面板中的 "以 HTML 格式撰写邮件" 设置。

  3. 在主 Thunderbird 窗口中,打开补丁的撰写窗口之前,使用工具→about:config 将以下设置设置为指示的值

    	mailnews.send_plaintext_flowed  => false
    	mailnews.wraplength             => 0
  4. 打开一个撰写窗口并单击外部编辑器图标。

  5. 在外部编辑器窗口中,读入补丁文件并正常退出编辑器。

旁注:可能可以使用 about:config 和以下设置来执行步骤 2,但尚未有人尝试。

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

contrib/thunderbird-patch-inline 中有一个脚本可以帮助您以简单的方式将补丁包含在 Thunderbird 中。要使用它,请执行上述步骤,然后使用该脚本作为外部编辑器。

KMail

这应该可以帮助您使用 KMail 内联提交补丁。

  1. 将补丁准备为文本文件。

  2. 单击 "新邮件"。

  3. 转到编辑器窗口中的 "选项" 下,并确保未设置 "自动换行"。

  4. 使用 "消息" → "插入文件…" 并插入补丁。

  5. 返回到撰写窗口:将您希望添加的任何其他文本添加到消息中,填写寻址和主题字段,然后按发送。

基本树信息

基本树信息块用于维护者或第三方测试人员了解补丁系列适用的确切状态。它由基本提交组成,这是一个众所周知的提交,它是项目历史记录的稳定部分,其他所有人都在此基础上工作,以及零个或多个先决补丁,这些是在飞行中尚未成为基本提交一部分的众所周知的补丁,需要在应用补丁之前按拓扑顺序应用到基本提交之上。

基本提交显示为 "base-commit: " 后跟提交对象名称的 40 位十六进制数。先决补丁显示为 "prerequisite-patch-id: " 后跟 40 位十六进制补丁 ID,可以通过将补丁传递给 git patch-id --stable 命令来获得。

假设在公共提交 P 之上,您应用了来自其他人的众所周知的补丁 X、Y 和 Z,然后构建了您的三个补丁系列 A、B、C,历史记录将如下所示

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

使用 git format-patch --base=P -3 C(或其变体,例如使用 --cover-letter 或使用 Z..C 代替 -3 C 来指定范围),基本树信息块显示在命令输出的第一个消息的末尾(第一个补丁或封面信),如下所示

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 生成补丁,并且 P、X、Y、Z 的标识符附加在第一个消息的末尾。

如果在 cmdline 中设置 --base=auto,它将自动计算基本提交,作为远程跟踪分支的 tip commit 和 cmdline 中指定的 revision-range 的合并基础。对于本地分支,在使用此选项之前,您需要通过 git branch --set-upstream-to 使其跟踪远程分支。

示例

  • 提取修订 R1 和 R2 之间的提交,并使用 git am 将它们应用到当前分支之上以进行 cherry-pick

    $ 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

    此外,它智能地检测和处理重命名和完整重写,以生成重命名补丁。重命名补丁减少了文本输出量,并且通常更容易审查。请注意,非 Git "patch" 程序无法理解重命名补丁,因此仅当您知道收件人使用 Git 来应用您的补丁时才使用它。

  • 从当前分支提取三个最顶层的提交,并将它们格式化为可电子邮件发送的补丁

    $ git format-patch -3

警告

请注意,即使合并提交是请求范围的一部分,format-patch 也会从输出中省略它们。一个简单的“补丁”不包含足够的信息,供接收方重现相同的合并提交。

GIT

属于 git[1] 套件的一部分

scroll-to-top