简体中文 ▾ 主题 ▾ 最新版本 ▾ 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. 单个提交 指定要输出当前分支尖端上不在 历史中的提交。

  2. 通用 表达式(参见 gitrevisions[7] 中的“SPECIFYING REVISIONS”部分)表示指定范围内的提交。

在单个 的情况下,第一条规则优先。要应用第二条规则,即格式化从历史开始到 的所有内容,请使用 --root 选项:git format-patch --root <commit>。如果您只想格式化 本身,可以使用 git format-patch -1 <commit>

默认情况下,每个输出文件从 1 开始按顺序编号,并使用提交消息的第一行(为文件名安全而处理)作为文件名。使用 --numbered-files 选项,输出文件名将仅是数字,不附加提交的第一行。输出文件的名称会打印到标准输出,除非指定了 --stdout 选项。

如果指定了 -o,输出文件将在 <dir> 中创建。否则,它们将在当前工作目录中创建。默认路径可以使用 format.outputDirectory 配置选项设置。-o 选项优先于 format.outputDirectory。即使 format.outputDirectory 指向其他位置,也要将补丁存储在当前工作目录中,请使用 -o .。所有目录组件都将被创建。

默认情况下,单个补丁的主题是 "[PATCH] ",后跟提交消息中直到第一个空行(参见 git-commit[1] 的 DISCUSSION 部分)的行内容。

当输出多个补丁时,主题前缀将变为 "[PATCH n/m] "。要强制为单个补丁添加 1/1,请使用 -n。要从主题中省略补丁号,请使用 -N

如果给定 --threadgit-format-patch 将生成 In-Reply-ToReferences 标头,使第二封及后续补丁邮件显示为对第一封邮件的回复;这也会生成一个 Message-ID 标头供引用。

选项

-p
--no-stat

生成纯补丁,不包含任何差异统计。

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

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

--output=<file>

输出到特定文件而不是标准输出。

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

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

--indent-heuristic

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

--no-indent-heuristic

禁用缩进启发式算法。

--minimal

花费额外时间以确保生成最小的差异。

--patience

使用“patience diff”算法生成差异。

--histogram

使用“histogram diff”算法生成差异。

--anchored=<text>

使用“anchored diff”算法生成差异。

此选项可以多次指定。

如果一行在源和目标中都存在,只存在一次,并且以 <text> 开头,则此算法会尝试阻止其在输出中显示为删除或添加。它内部使用“patience diff”算法。

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

选择一种差异算法。变体如下:

default
myers

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

minimal

花费额外时间以确保生成最小的差异。

patience

生成补丁时使用“patience diff”算法。

histogram

此算法扩展了 patience 算法以“支持低出现率的常见元素”。

例如,如果您将 diff.algorithm 变量配置为非默认值,但希望使用默认值,则必须使用 --diff-algorithm=default 选项。

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

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

输出扩展头信息的精简摘要,例如文件创建或删除(“new”或“gone”,可选 +l 表示符号链接)和模式更改(+x-x 分别用于添加或删除可执行位)在 diffstat 中。信息放置在文件名部分和图形部分之间。隐含 --stat

--numstat

--stat 类似,但以十进制表示法显示添加和删除的行数以及未缩写的路径名,使其更便于机器处理。对于二进制文件,输出两个 - 而不是显示 0 0

--shortstat

仅输出 --stat 格式的最后一行,其中包含修改文件的总数,以及添加和删除的行数。

-X [<param>,...]
--dirstat[=<param>,...]

输出每个子目录的相对更改量分布。--dirstat 的行为可以通过传递一个逗号分隔的参数列表来自定义。默认值由 diff.dirstat 配置变量控制(参见 git-config[1])。以下参数可用:

changes

通过计算从源中删除或添加到目标中的行数来计算 dirstat 数字。这忽略了文件中纯代码移动的数量。换句话说,重新排列文件中的行不像其他更改那样被计算。当未给出参数时,这是默认行为。

lines

通过执行常规的基于行的差异分析,并汇总已删除/添加的行数来计算 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”行上显示前几个字符,而是显示完整的原图像和后图像 blob 对象名称。

--binary

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

--abbrev[=<n>]

在 diff-raw 格式输出和 diff-tree 标题行中,不显示完整的 40 字节十六进制对象名称,而是显示最短的前缀,该前缀至少有 <n> 个十六进制数字长,并且唯一引用该对象。在 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

省略删除的原始图像,即只打印标题,而不打印原始图像和 /dev/null 之间的差异。生成的补丁不适用于 patchgit apply;这仅适用于那些只想专注于审查更改后文本的人。此外,输出显然缺乏足够的信息来反向应用此类补丁,即使是手动,因此得名此选项。

-B 一起使用时,也会省略删除/创建对的删除部分中的原始图像。

-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=<number>

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

-W
--function-context

显示整个函数作为每次更改的上下文行。函数名称的确定方式与 git diff 生成补丁块头的方式相同(参见 gitattributes[5] 中“Defining a custom hunk-header”)。

--ext-diff

允许执行外部差异辅助程序。如果您使用 gitattributes[5] 设置了外部差异驱动程序,则需要与 git-log[1] 等命令一起使用此选项。

--no-ext-diff

禁止外部差异驱动程序。

--textconv
--no-textconv

允许(或禁止)在比较二进制文件时运行外部文本转换过滤器。有关详细信息,请参见 gitattributes[5]。由于 textconv 过滤器通常是单向转换,因此生成的差异适合人工阅读,但无法应用。因此,textconv 过滤器默认仅为 git-diff[1]git-log[1] 启用,而不为 git-format-patch[1] 或差异底层命令启用。

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

在生成差异时忽略对子模块的更改。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 中显示为不存在。这两个选项都是实验性的,将来可能会被删除。

有关这些通用选项的更详细说明,另请参见 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] 中的签收选项。

--stdout

将所有提交以 mbox 格式打印到标准输出,而不是为每个提交创建一个文件。

--attach[=<boundary>]

创建 multipart/mixed 附件,其中第一部分是提交消息,第二部分是补丁本身,带有 Content-Disposition: attachment

--no-attach

禁用附件的创建,覆盖配置设置。

--inline[=<boundary>]

创建 multipart/mixed 附件,其中第一部分是提交消息,第二部分是补丁本身,带有 Content-Disposition: inline

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

控制添加 In-Reply-ToReferences 标头,使第二封及后续邮件显示为对第一封邮件的回复。还控制生成用于引用的 Message-ID 标头。

可选的 <style> 参数可以是 shallowdeepshallow 线程将每封邮件作为对系列头部的回复,头部从封面信、--in-reply-to 和第一封补丁邮件中选择,按此顺序。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> 的回复,从而避免中断线程以提供新的补丁系列。

--ignore-if-in-upstream

不包含与 <until>..<since> 中提交匹配的补丁。这将检查所有可从 <since> 访问但不可从 <until> 访问的补丁,并将其与正在生成的补丁进行比较,任何匹配的补丁都将被忽略。

--always

包含不引入任何更改的提交的补丁,默认情况下会省略这些补丁。

--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"),但使用此类 reroll-count 的缺点是,与先前版本的 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

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

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

使用“Q-编码”(RFC 2047 中描述)对包含非 ASCII 字符的电子邮件头进行编码,而不是原样输出头。默认为 format.encodeEmailHeaders 配置变量的值。

--interdiff=<previous>

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

--range-diff=<previous>

作为审阅者辅助,在封面信中插入一个范围差异(参见 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=<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 配置选项的讨论,以使用此工作流)。

默认是 --no-notes,除非设置了 format.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>]

记录基础树信息以识别补丁系列适用的状态。有关详细信息,请参见下面的 BASE TREE INFORMATION 部分。如果 <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 邮箱格式,带有一个固定的“魔术”时间戳,表示该文件是 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] 重新生成补丁之前对其进行 rebase。

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

  • 同时,也检查 infofinal-commit 文件。如果 final-commit 中的内容与您希望在提交日志消息中看到的内容不完全一致,则接收方在应用您的补丁时很可能会手动编辑日志消息。诸如补丁电子邮件中的“Hi, this is my first patch.\n”之类的文本应在表示提交消息结束的三划线之后出现。

MUA 特定提示

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

GMail

GMail 的网页界面没有任何关闭行包装的方法,因此它会破坏您发送的任何电子邮件。但是,您可以使用 "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 (附加组件)

安装可从 https://addons.mozilla.org/thunderbird/addon/toggle-word-wrap/ 获取的 Toggle 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 扩展:AboutConfig 来自 https://mjg.github.io/AboutConfig/ 和 External Editor 来自 https://globs.org/articles.php?lng=en&pg=8

  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,该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的标识符会附加到第一个消息的末尾。

如果在命令行中设置--base=auto,它将自动计算基础提交,作为远程跟踪分支的尖端提交与命令行中指定的修订范围的合并基础。对于本地分支,在使用此选项之前,您需要通过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