Git
简体中文 ▾ Topics ▾ Latest version ▾ git-format-patch last updated in 2.43.2

名称

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] [--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 <提交>" 开始,带有固定的 "Mon Sep 17 00:00:00 2001" 的日期,以帮助 "file(1)" 等程序识别该文件是该命令的输出,记录作者身份、作者日期和修改标题的字段(取自提交日志信息的第一段)。

  • 提交日志信息的第二段和后续段落。

  • “补丁”,也就是该提交和其父辈之间的 "diff -p --stat" 输出(见 git-diff[1])。

The log message and the patch are separated by a line with a three-dash line.

有两种方法可以指定要对哪些提交进行操作。

  1. A single commit, <since>, specifies that the commits leading to the tip of the current branch that are not in the history that leads to the <since> to be output.

  2. 通用的 <修订范围> 表达式(见 gitrevisions[7]中的 "指定修订" 一节)表示指定范围内的提交。

在只有一个 <提交> 的情况下,第一条规则具有优先权。 要应用第二条规则,即格式化从历史开始到 <提交> 为止的所有内容,使用 --root 选项:git format-patch --root <提交>。 如果你只想格式化 <提交> 本身,你可以用`git format-patch -1 <提交>`来做。

默认情况下,每个输出文件从 1 开始依次编号,并使用提交信息的第一行(为保证路径名的安全而进行了调整)作为文件名。使用 --numbered-files 选项,输出文件名将只有数字,而没有附加提交信息的第一行。 除非指定 --stdout 选项,否则输出文件的名称将被打印到标准输出。

如果指定了 -o,输出文件将在<目录>创建。 否则,它们将在当前工作目录下创建。默认路径可以通过 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

生成没有任何差异状态(diffstats)的普通补丁。

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

生成带有 <n> 行上下文的差异,而不是通常的 3 行。暗含 --patch 选项。

--output=<文件>

输出到一个特定的文件,而不是标准输出。

--output-indicator-new=<字符>
--output-indicator-old=<字符>
--output-indicator-context=<字符>

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

--indent-heuristic

启用启发式的缩进区块的方法,使得补丁更易读。这是默认选项。

--no-indent-heuristic

禁用启发式缩进。

--minimal

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

--patience

使用 "patience diff" 算法生成差异。

--histogram

使用 "histogram diff" 算法生成差异。

--anchored=<文本>

使用 "anchored diff" 算法生成差异。

这个选项可以被指定多次。

如果某一个行同时存在于来源和目标中,各只出现一次,以这个文本开头,这个算法试图防止它在输出中以删除或添加的形式出现。它在内部使用了 "patience diff" 算法。

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

选择差异算法。有如下可选项:

default, myers

基本的贪婪差异算法。当前是默认设置。

minimal

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

patience

使用 "patience diff" 算法时产生的补丁。

histogram

该算法将耐心算法扩展为 “支持低发生率的常见元素”。

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

--stat[=<宽度>[,<名称宽度>[,<数值>]]]

Generate a diffstat. By default, as much space as necessary will be used for the filename part, and the rest for the graph part. Maximum width defaults to terminal width, or 80 columns if not connected to a terminal, and can be overridden by <width>. The width of the filename part can be limited by giving another width <name-width> after a comma or by setting diff.statNameWidth=<width>. The width of the graph part can be limited by using --stat-graph-width=<width> or by setting diff.statGraphWidth=<width>. Using --stat or --stat-graph-width affects all commands generating a stat graph, while setting diff.statNameWidth or diff.statGraphWidth does not affect git format-patch. By giving a third parameter <count>, you can limit the output to the first <count> lines, followed by ... if there are more.

这些参数也可以用 --stat-width=<宽度>--stat-name-width=<名称宽度>--stat-count=<数量> 单独设置。

--compact-summary

在差异状态中输出扩展头信息的压缩摘要,如文件的创建或删除("new" 或 "good"。如果是符号链接,则为 "+l")和模式变化("+x" 或 "-x" 分别用于添加或删除可执行位)。这些信息被放在文件名部分和图形部分之间。暗含 --stat 选项。

--numstat

Similar to --stat, but shows number of added and deleted lines in decimal notation and pathname without abbreviation, to make it more machine friendly. For binary files, outputs two - instead of saying 0 0.

--shortstat

只输出使用 --stat 选项输出的最后一行,包含修改的文件总数,添加和删除的行数。

-X[<参数1,参数2,…​>]
--dirstat[=<参数1,参数2,…​>]

Output the distribution of relative amount of changes for each sub-directory. The behavior of --dirstat can be customized by passing it a comma separated list of parameters. The defaults are controlled by the diff.dirstat configuration variable (see git-config[1]). The following parameters are available:

changes

Compute the dirstat numbers by counting the lines that have been removed from the source, or added to the destination. This ignores the amount of pure code movements within a file. In other words, rearranging lines in a file is not counted as much as other changes. This is the default behavior when no parameter is given.

lines

通过做常规基于行的差异分析,计算分布状态的数字,并将删除/添加的行数相加。(对于二进制文件,用 64 字节的块来计算,因为二进制文件没有行的概念)。在使用 --dirstat 时这个选项的行为开销比 changes 更大,但会对文件中重新排列的行进行计数。其得到的输出结果与其他的 --*stat 选项一致。

files

Compute the dirstat numbers by counting the number of files changed. Each changed file counts equally in the dirstat analysis. This is the computationally cheapest --dirstat behavior, since it does not have to look at the file contents at all.

cumulative

Count changes in a child directory for the parent directory as well. Note that when using cumulative, the sum of the percentages reported may exceed 100%. The default (non-cumulative) behavior can be specified with the noncumulative parameter.

<limit>

An integer parameter specifies a cut-off percent (3% by default). Directories contributing less than this percentage of the changes are not shown in the output.

例如:下面的参数会统计更改的文件,同时忽略占更改文件总数 10% 以下的目录,并累积父目录中的子目录计数:--dirstat=files,10,cumulative

--cumulative

--dirstat=cumulative 同义

--dirstat-by-file[=<参数1,参数2>…​]

Synonym for --dirstat=files,<param1>,<param2>…​

--summary

输出扩展头信息,如创建、重命名和模式变化等,的压缩摘要。

--no-renames

关闭重命名检测,即使配置文件给出的默认是这样做。

--[no-]rename-empty

是否使用空的数据对象作为重命名源。

--full-index

在生成补丁格式输出时,在 index(索引)行上显示完整的图像前和图像后数据对象名称,而不仅是前几个字符。

--binary

除了 --full-index 输出的差异之外,输出二进制的差异。其可以用 git-apply 命令来应用。暗含 --patch 选项。

--abbrev[=<n>]

Instead of showing the full 40-byte hexadecimal object name in diff-raw format output and diff-tree header lines, show the shortest prefix that is at least <n> hexdigits long that uniquely refers the object. In diff-patch output format, --full-index takes higher precedence, i.e. if --full-index is specified, full blob names will be shown regardless of --abbrev. Non default number of digits can be specified with --abbrev=<n>.

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

将完整的重写更改切分成删除和创建对(pair)。这有两个目的:

它会影响决定更改形式的阈值,当单个文件内修改总量达到一定值时,会认为该文件进行了完全重写,而不是将一系列删除和插入操作视为修改。如果视为多个删除和插入修改,修改中的行可能会碰巧在文本上与原文一致,从而被当作上下文。选项中的数字 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>]

Detect copies as well as renames. See also --find-copies-harder. If n is specified, it has the same meaning as for -M<n>.

--find-copies-harder

For performance reasons, by default, -C option finds copies only if the original file of the copy was modified in the same changeset. This flag makes the command inspect unmodified files as candidates for the source of copy. This is a very expensive operation for large projects, so use it with caution. Giving more than one -C option has the same effect.

-D
--irreversible-delete

删除时省略原内容,即只打印头信息,而不打原内容和 /dev/null 之间的差异。所产生的补丁并不是要用于 patchgit apply;这只是为了让人们只专注于审查修改后的文本。此外,输出结果显然缺乏足够的信息来反转,或手动应用这样一个补丁,因此这个选项的名称如此。

当与 -B 一起使用时,也省略删除/创建对中删除部分的原内容。

-l<数量>

The -M and -C options involve some preliminary steps that can detect subsets of renames/copies cheaply, followed by an exhaustive fallback portion that compares all remaining unpaired destinations to all relevant sources. (For renames, only remaining unpaired sources are relevant; for copies, all original sources are relevant.) For N sources and destinations, this exhaustive check is O(N^2). This option prevents the exhaustive portion of rename/copy detection from running if the number of source/destination files involved exceeds the specified number. Defaults to diff.renameLimit. Note that a value of 0 is treated as unlimited.

-O<顺序控制文件>

Control the order in which files appear in the output. This overrides the diff.orderFile configuration variable (see git-config[1]). To cancel diff.orderFile, use -O/dev/null.

The output order is determined by the order of glob patterns in <orderfile>. All files with pathnames that match the first pattern are output first, all files with pathnames that match the second pattern (but not the first) are output next, and so on. All files with pathnames that do not match any pattern are output last, as if there was an implicit match-all pattern at the end of the file. If multiple pathnames have the same rank (they match the same pattern but no earlier patterns), their output order relative to each other is the normal order.

<顺序控制文件> 格式如下:

  • 空白行会被忽略,因此可以用它们作为分隔符,以保证可读性。

  • Lines starting with a hash ("#") are ignored, so they can be used for comments. Add a backslash ("\") to the beginning of the pattern if it starts with a hash.

  • 每一行都包含一个模式。

Patterns have the same syntax and semantics as patterns used for fnmatch(3) without the FNM_PATHNAME flag, except a pathname also matches a pattern if removing any number of the final pathname components matches the pattern. For example, the pattern "foo*bar" matches "fooasdfbar" and "foo/bar/baz/asdf" but not "foobarx".

--skip-to=<文件>
--rotate-to=<文件>

Discard the files before the named <file> from the output (i.e. skip to), or move them to the end of the output (i.e. rotate to). These options were invented primarily for the use of the git difftool command, and may not be very useful otherwise.

--relative[=<路径>]
--no-relative

When run from a subdirectory of the project, it can be told to exclude changes outside the directory and show pathnames relative to it with this option. When you are not in a subdirectory (e.g. in a bare repository), you can name which subdirectory to make the output relative to by giving a <path> as an argument. --no-relative can be used to countermand both diff.relative config option and previous --relative.

-a
--text

将一切输入文件视为文本。

--ignore-cr-at-eol

在进行比较时,忽略行末的回车。

--ignore-space-at-eol

忽略行尾空格的变化。

-b
--ignore-space-change

Ignore changes in amount of whitespace. This ignores whitespace at line end, and considers all other sequences of one or more whitespace characters to be equivalent.

-w
--ignore-all-space

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

--ignore-blank-lines

忽略空白行的变化。

-I<正则表达式>
--ignore-matching-lines=<正则表达式>

Ignore changes whose all lines match <regex>. This option may be specified more than once.

--inter-hunk-context=<行数>

Show the context between diff hunks, up to the specified number of lines, thereby fusing hunks that are close to each other. Defaults to diff.interHunkContext or 0 if the config option is unset.

-W
--function-context

Show whole function as context lines for each change. The function names are determined in the same way as git diff works out patch hunk headers (see Defining a custom hunk-header in gitattributes[5]).

--ext-diff

允许执行外部差异器。如果你用 gitattributes[5] 设置了一个外部差异驱动程序,你需要在 git-log[1] 和相关命令中使用这个选项。

--no-ext-diff

禁止使用外部差异器。

--textconv
--no-textconv

允许(或不允许)在比较二进制文件时运行外部文本转换过滤器。详情请参见 gitattributes[5] 。由于文本转换过滤器通常是单向转换,因此产生的差异适合人类用户使用,但不能应用(apply)。因此默认情况下,只有 git-diff[1]git-log[1] 启用文本转换过滤器,而 git-format-patch[1] 或 diff plumbing 命令则不启用。

--ignore-submodules[=<when>]

Ignore changes to submodules in the diff generation. <when> can be either "none", "untracked", "dirty" or "all", which is the default. Using "none" will consider the submodule modified when it either contains untracked or modified files or its HEAD differs from the commit recorded in the superproject and can be used to override any settings of the ignore option in git-config[1] or gitmodules[5]. When "untracked" is used submodules are not considered dirty when they only contain untracked content (but they are still scanned for modified content). Using "dirty" ignores all changes to the work tree of submodules, only changes to the commits stored in the superproject are shown (this was the behavior until 1.7.0). Using "all" hides all changes to submodules.

--src-prefix=<前缀>

显示给定的源前缀而不是 "a/"。

--dst-prefix=<前缀>

显示给定的目标前缀,而不是“b/”。

--no-prefix

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

--default-prefix

Use the default source and destination prefixes ("a/" and "b/"). This is usually the default already, but may be used to override config such as diff.noprefix.

--line-prefix=<prefix>

在每一行输出前加上一个额外的前缀。

--ita-invisible-in-index

By default entries added by "git add -N" appear as an existing empty file in "git diff" and a new file in "git diff --cached". This option makes the entry appear as a new file in "git diff" and non-existent in "git diff --cached". This option could be reverted with --ita-visible-in-index. Both options are experimental and could be removed in future.

关于这些常用选项的更多解释,请参见 gitdiffcore[7]

-<n>

从最上面的 <n> 个提交中准备补丁。

-o <目录>
--output-directory <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>]

创建多部分/混合附件,第一部分是提交信息,第二部分是补丁本身,Content-Disposition: attachment

--no-attach

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

--inline[=<boundary>]

创建 multipart/mixed 附件,第一部分是提交信息,第二部分是补丁本身,使用 Content-Disposition: inline

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

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

可选的 <风格> 参数可以是 shallowdeep。 ‘浅’ 线程使每封邮件都是对该系列的头的回复,其中头是从封面信、--in-reply-to 和第一个补丁邮件中选择的,按这个顺序。 ‘深’ 线程使每封邮件都是对前一封的回复。

默认是 --no-thread,除非设置了 format.thread 配置。 没有参数的 --thread 等同于 --thread=shallow

请注意,git send-email 的默认设置是对邮件本身进行线程处理。 如果你想让 git format-patch 负责线程,你要确保 git send-email 的线程被禁用。

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

使第一封邮件(或所有带有 --no-thread 的邮件)作为给定的 <消息 id> 的回复出现,这可以避免破坏线程以提供一个新的补丁系列。

--ignore-if-in-upstream

不包括与 <until>…​<since> 中的提交相匹配的补丁。 这将检查所有可从 <since> 到达但不在 <until> 的补丁,并将它们与正在生成的补丁进行比较,任何匹配的补丁都将被忽略。

--always

包括那些没有引入任何变化的提交的补丁,这些补丁默认是省略的。

--cover-from-description=<mode>

控制求职信的哪些部分将使用分支机构的描述自动填充。

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

如果 <模式>subject,分支描述的第一段将填入求职信的主题。描述的其余部分将填充到求职信的正文中。

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

如果 <模式>none,求职信的主题和正文都将被填充为占位符文本。

--description-file=<file>

使用 <文件> 的内容而不是分支说明来生成求职信。

--subject-prefix=<subject prefix>

Instead of the standard [PATCH] prefix in the subject line, instead use [<subject prefix>]. This can be used to name a patch series, and can be combined with the --numbered option.

配置变量 format.subjectPrefix 也可用于配置主题前缀,以适用于指定仓库的所有补丁。这在接收多个仓库补丁的邮件列表中通常很有用,可用于消除补丁的歧义(例如值为 "PATCH my-project")。

--filename-max-length=<n>

代替标准的 64 字节,将生成的输出文件名压缩到 <n> 字节左右(太短的值会被默默提升到合理的长度)。 默认为 format.filenameMaxLength 配置变量的值,如果没有配置,则为 64。

--rfc

Prepends "RFC" to the subject prefix (producing "RFC PATCH" by default). RFC means "Request For Comments"; use this when sending an experimental patch for discussion rather than application.

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

Mark the series as the <n>-th iteration of the topic. The output filenames have v<n> prepended to them, and the subject prefix ("PATCH" by default, but configurable via the --subject-prefix option) has ` v<n>` appended to it. E.g. --reroll-count=4 may produce v4-0001-add-makefile.patch file that has "Subject: [PATCH v4 1/20] Add makefile" in it. <n> does not have to be an integer (e.g. "--reroll-count=4.4", or "--reroll-count=4rev2" are allowed), but the downside of using such a reroll-count is that the range-diff/interdiff with the previous version does not state exactly which version the new iteration is compared against.

--to=<e-mail>

在邮件标题中增加一个 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-encoding"(在RFC 2047中描述)对有非 ASCII 字符的邮件头进行编码,而不是逐字输出邮件头。默认为 format.encodeEmailHeaders 配置变量的值。

--interdiff=<previous>

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

--range-diff=<previous>

作为审查员的辅助工具,在封面信中插入一个 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])。

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

Works just like --signature except the signature is read from a file.

--suffix=.<sfx>

不使用 .patch 作为生成文件名的后缀,而使用指定的后缀。 一个常见的选择是 --suffix=.txt。 将此留空将删除 .patch 后缀。

请注意,前导字符不一定是点;例如,你可以使用 --suffix=-patch 来获得 0001-description-of-my-change-patch

-q
--quiet

不要将生成的文件名打印到标准输出。

--no-binary

不输出二进制文件中的变化内容,而是显示这些文件变化的通知。 使用该选项生成的补丁不能被正确应用,但它们对代码审查仍然有用。

--zero-commit

在每个补丁的 From 头中输出一个全零的哈希值,而不是提交的哈希值。

--[no-]base[=<commit>]

记录基树信息,以确定该补丁系列所适用的状态。 详见下面的基树信息部分。如果 <提交> 是 "auto",就会自动选择一个基数提交。--no-base 选项会覆盖 format.useAutoBase 配置。

--root

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

--progress

在生成补丁时在标准错误流上显示进度报告。

配置

你可以指定额外的邮件标题行添加到每封邮件中,主题前缀和文件后缀的默认值,在输出多个补丁时对补丁进行编号,添加 "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
(见提交 c2330e286f68f1c408b4aa6515ba49d57f05beae 评论)

为 ia64 做同样的事情,这样我们就可以有光滑和修长的外观了。
...

通常情况下,它会被放在 MUA 的 drafts 文件夹中,被编辑以添加及时的评论,这些评论不应该被放在 changelog 中的三个破折号之后,然后以消息的形式发送,在我们的例子中,其正文以 "arch/arm config files were…​" 开始。 在接收端,读者可以将有趣的补丁保存在 UNIX 邮箱中,并通过 git-am[1] 应用它们。

当一个补丁是正在进行的讨论的一部分时,由 git format-patch 生成的补丁可以进行调整,以利用 git am --scissors 功能。 在你对讨论的回应之后,有一行只由 "-- >8 --"(剪刀和打孔)组成,后面是去除不必要的头域的补丁:

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

对我来说是有意义的。 这个补丁怎么样?

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

使用 python 脚本对 arch/arm 配置文件进行了精简
...

当用这种方式发送补丁时,大多数情况下是发送你自己的补丁,所以除了 "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/ 子目录,看看 "补丁" 文件包含哪些内容,并检查上面提到的常见损坏模式。

  • 同时,还要检查 infofinal-commit 文件。 如果 final-commit 中的内容与你希望在提交日志信息中看到的不完全一样,那么很可能接收者在应用你的补丁时最终会手工编辑日志信息。 补丁邮件中的 "Hi, this is my first patch.\n" 等内容应该出现在提交信息末尾的三折线之后。

针对 Mua 的提示

这里有一些关于如何使用各种邮件工具成功地在线提交补丁的提示。

GMail

GMail 没有办法在网页界面上关闭换行,所以它会把你发送的任何邮件弄得一团糟。 然而,你可以使用 "git send-email",通过 GMail 的 SMTP 服务器发送你的补丁,或者使用任何 IMAP 电子邮件客户端连接到谷歌的 IMAP 服务器,并通过它转发电子邮件。

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

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

Thunderbird

默认情况下,Thunderbird 会将邮件包裹起来,并将其标记为 format=flowed,这两种情况都会使 Git 无法使用这些邮件。

有三种不同的方法:使用插件来关闭换行,配置 Thunderbird 使其不纠缠补丁,或者使用外部编辑器来防止 Thunderbird 纠缠补丁。

办法1(附加的)

安装 Toggle Word Wrap 插件,该插件可从 https://addons.mozilla.org/thunderbird/addon/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,等等),而且补丁不会被弄乱。

方法三(外部编辑)

需要以下 Thunderbird 扩展: http://aboutconfig.mozdev.org/ 中的 AboutConfig和http://globs.org/articles.php?lng=en&pg=8 中的 External Editor

  1. 用你选择的方法把补丁准备成一个文本文件。

  2. 在打开撰写窗口之前,使用 Edit→Account Settingd 取消勾选要用来发送补丁的账户的 "Composition & Addressing" 面板中的 "Compose messages in HTML format" 设置。

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

    	mailnews.send_plaintext_flowed  => false
    	mailnews.wraplength             => 0
  4. 打开一个作曲窗口,点击外部编辑器图标。

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

题外话:也许可以用 about:config 和以下设置来完成第二步,但还没有人试过。

	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. 点击 "New Mail"。

  3. 在合成器窗口的 "Otions" 下,确保没有设置 "Word warp"。

  4. Use Message → Insert file…​ 并插入补丁。

  5. 回到撰写窗口:在信息中添加你想要的任何其他文本,完成地址和主题字段,然后按发送。

基准树信息

基准树信息块用于维护者或第三方测试人员了解补丁系列所适用的确切状态。它由 ‘基本提交’ 和零个或多个 ‘前提补丁’ 组成,前者是众所周知的提交,是项目历史中稳定部分的一部分,而后者是正在运行的知名补丁,还不是 ‘基本提交’ 的一部分,在应用这些补丁之前需要在 ‘基本提交’ 之上按拓扑顺序应用。

‘基本提交’ 显示为 "base-commit: ",后面是提交对象名称的 40-hex。 ‘先决补丁’ 显示为 "prerequisite-patch-id: ",后面是 40-hex 的 “补丁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 的标识符被附加在第一条信息的末尾。

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

实例

  • 提取 R1 和 R2 修订版之间的提交,并用 "git am" 将其应用于当前分支之上,以拣选它们:

    $ git format-patch -k --stdout R1..R2 | git am -3 -k
  • 提取所有在当前分支但不在原生分支中的提交:

    $ git format-patch origin

    每次提交都会在当前目录下创建一个单独的文件。

  • 提取自项目开始以来所有导致 origin 的提交:

    $ git format-patch --root origin
  • 与前者相同:

    $ git format-patch -M -B origin

    此外,它还能智能地检测和处理重命名和完全重写,以产生重命名补丁。 重命名补丁减少了文本输出的数量,一般来说,它更容易审查。 注意,非 Git 的 “补丁” 程序不会理解重命名补丁,所以只有当你知道收件人使用 Git 来应用你的补丁时才会使用它。

  • 从当前分支中提取三个最重要的提交,并将其格式化为可发送电子邮件的补丁:

    $ git format-patch -3

注意事项

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

GIT

属于 git[1] 文档

scroll-to-top