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

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

选项

-p
--no-stat

生成不带任何 diffstat 的纯补丁。

-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

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

--histogram

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

--anchored=<text>

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

此选项可以多次指定。

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

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

选择差异算法。变体如下所示:

defaultmyers

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

minimal

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

patience

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

histogram

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

例如,如果你将 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 会影响所有生成 stat 图形的命令,而设置 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”以添加或删除可执行位)。信息放在文件名部分和图形部分之间。隐含 --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

在生成补丁格式输出时,在“索引”行上显示完整的预图像和后图像 Blob 对象名称,而不是前几个字符。

--binary

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

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

忽略 EOL 处空格的更改。

-b
--ignore-space-change

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

-w
--ignore-all-space

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

--ignore-blank-lines

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

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

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

--inter-hunk-context=<lines>

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

-W
--function-context

为每个更改显示整个函数作为上下文行。函数名称的确定方式与git diff确定补丁块标题的方式相同(请参阅gitattributes[5]中的“定义自定义块标题”)。

--ext-diff

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

--no-ext-diff

禁止外部 diff 驱动程序。

--textconv
--no-textconv

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

--ignore-submodules[=<when>]

在差异生成中忽略对子模块的更改。<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>个提交中准备补丁。

-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附件,其中第一部分是提交消息,第二部分是补丁本身,并带有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 表示“征求意见稿”;在发送实验性补丁以供讨论而不是应用时使用此选项。 “--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=<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>

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

--range-diff=<previous>

作为审阅者辅助,将范围差异(参见git-range-diff[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>]

记录基本树信息以识别补丁系列适用的状态。有关详细信息,请参见下面的基本树信息部分。如果<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 <[email protected]>
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 的网页界面没有提供关闭自动换行的方式,因此它会破坏您发送的任何邮件。但是,您可以使用“git send-email”通过 Gmail SMTP 服务器发送补丁,或者使用任何 IMAP 邮件客户端连接到 Google IMAP 服务器并通过它转发邮件。

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

有关使用 IMAP 接口提交的提示,请参阅git-imap-send[1]的示例部分。

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 扩展:来自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 的标识符将附加到第一条消息的末尾。

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

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

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

    $ git format-patch -3

注意事项

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

另请参阅

Git

git[1]套件的一部分

scroll-to-top