简体中文 ▾ 主题 ▾ 最新版本 ▾ git-diff-files 上次更新于 2.48.0

名称

git-diff-files - 比较工作区和索引中的文件

概要

git diff-files [-q] [-0 | -1 | -2 | -3 | -c | --cc] [<common-diff-options>] [<path>…​]

描述

比较工作区和索引中的文件。如果指定了路径,则只比较这些命名路径。否则,比较索引中的所有条目。输出格式与 git diff-indexgit diff-tree 相同。

选项

-p
-u
--patch

生成补丁(参见 使用 -p 生成补丁文本)。

-s
--no-patch

禁止所有来自差异机制的输出。对于像 git show 这种默认显示补丁的命令,它用于抑制输出,或取消别名中命令行上早先出现的 --patch--stat 等选项的效果。

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

生成包含 <n> 行上下文(而不是通常的三行)的 diff。隐含 --patch

--output=<file>

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

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

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

--raw

以原始格式生成 diff。这是默认设置。

--patch-with-raw

-p --raw 的同义词。

--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 分别用于添加或删除可执行位)。信息放在文件名部分和图形部分之间。隐含 --stat

--numstat

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

--shortstat

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

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

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

changes

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

lines

通过执行常规的基于行的差异分析,并汇总移除/添加的行数来计算目录统计数字。(对于二进制文件,计算 64 字节块,因为二进制文件没有自然的行的概念)。这是一种比 changes 行为更昂贵的 --dirstat 行为,但它会将文件内部重新排列的行与其他更改一样计算在内。结果输出与您从其他 --*stat 选项获得的输出一致。

files

通过计算更改的文件数量来计算目录统计数字。每个更改的文件在目录统计分析中同等计数。这是计算成本最低的 --dirstat 行为,因为它根本不需要查看文件内容。

cumulative

同时计算子目录中对父目录的更改。请注意,使用 cumulative 时,报告的百分比总和可能超过 100%。默认(非累积)行为可以通过 noncumulative 参数指定。

<limit>

一个整数参数,指定一个截止百分比(默认为 3%)。对更改贡献低于此百分比的目录不会显示在输出中。

示例:以下将计算更改的文件,同时忽略更改文件总数少于 10% 的目录,并在父目录中累积子目录计数:--dirstat=files,10,cumulative

--cumulative

--dirstat=cumulative 的同义词。

--dirstat-by-file[=<param>,...]

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

--summary

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

--patch-with-stat

-p --stat 的同义词。

-z

当给定了 --raw--numstat--name-only--name-status 时,不混淆路径名,并使用 NUL 作为输出字段终止符。

如果没有此选项,包含“不寻常”字符的路径名将按照配置变量 core.quotePath 的解释进行引用(参见 git-config[1])。

--name-only

仅显示后像树中每个已更改文件的名称。文件名通常以 UTF-8 编码。有关更多信息,请参阅 git-log[1] 手册页中关于编码的讨论。

--name-status

仅显示每个更改文件的名称和状态。有关状态字母含义的说明,请参阅 --diff-filter 选项的描述。与 --name-only 一样,文件名通常以 UTF-8 编码。

--submodule[=<format>]

指定如何显示子模块中的差异。当指定 --submodule=short 时,使用 short 格式。此格式只显示范围开始和结束时提交的名称。当指定 --submodule--submodule=log 时,使用 log 格式。此格式列出范围内的提交,就像 git-submodule[1] summary 所做的那样。当指定 --submodule=diff 时,使用 diff 格式。此格式显示提交范围内的子模块内容更改的内联差异。默认为 diff.submodule,如果未设置配置选项则为 short 格式。

--color[=<when>]

显示彩色差异。--color(即没有 =<when>)与 --color=always 相同。<when> 可以是 alwaysneverauto 之一。

--no-color

关闭彩色 diff。它与 --color=never 相同。

--color-moved[=<mode>]

移动的代码行会以不同的颜色着色。如果未给出此选项,<mode> 默认为 no;如果给出了没有模式的选项,则默认为 zebra。模式必须是以下之一:

no

移动的行不进行高亮显示。

default

zebra 的同义词。未来可能会更改为更合理的模式。

plain

在某个位置添加但在另一个位置删除的任何行都将使用 color.diff.newMoved 着色。类似地,color.diff.oldMoved 将用于在差异中其他地方添加的已删除行。此模式会选取任何移动的行,但在审查中用于确定代码块是否在没有置换的情况下移动则不太有用。

blocks

贪婪地检测至少20个字母数字字符的移动文本块。检测到的块使用 color.diff.(old|new)Moved 颜色进行绘制。相邻块无法区分。

zebra

移动文本块的检测方式与 blocks 模式相同。这些块使用 color.diff.(old|new)Moved 颜色或 color.diff.(old|new)MovedAlternative 进行绘制。两种颜色之间的变化表示检测到新的块。

dimmed-zebra

zebra 类似,但对移动代码中不重要的部分进行额外的弱化处理。两个相邻块的边界行被认为是有趣的,其余部分则不有趣。dimmed_zebra 是一个已弃用的同义词。

--no-color-moved

关闭移动检测。这可以用于覆盖配置设置。它与 --color-moved=no 相同。

--color-moved-ws=<mode>,...

这配置了在执行 --color-moved 的移动检测时如何忽略空白。这些模式可以作为逗号分隔的列表给出:

no

执行移动检测时不忽略空白。

ignore-space-at-eol

忽略行尾空格的更改。

ignore-space-change

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

ignore-all-space

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

allow-indentation-change

在移动检测中最初忽略所有空白,然后仅当每行的空白更改相同时,才将移动的代码块分组为一个块。这与其他模式不兼容。

--no-color-moved-ws

执行移动检测时不忽略空白。这可以用于覆盖配置设置。它与 --color-moved-ws=no 相同。

--word-diff[=<mode>]

默认情况下,单词由空白分隔;参见下面的 --word-diff-regex<mode> 默认为 plain,并且必须是以下之一:

color

仅使用颜色高亮显示更改的单词。隐含 --color

plain

显示单词为 [-已删除-]{已添加}。如果分隔符出现在输入中,则不尝试转义,因此输出可能会模糊不清。

porcelain

使用一种特殊的基于行的格式,旨在供脚本消费。添加/删除/未更改的运行以通常的统一差异格式打印,行首以 +/-/` ` 字符开头,并延伸到行尾。输入中的换行符由其单独一行上的波浪号 ~ 表示。

none

再次禁用单词 diff。

请注意,尽管第一个模式的名称如此,如果启用,所有模式都使用颜色高亮显示更改的部分。

--word-diff-regex=<regex>

使用 <regex> 来决定什么是单词,而不是将非空白字符的连续序列视为一个单词。除非已启用,否则这也隐含 --word-diff

<regex> 的每个不重叠匹配都被视为一个单词。这些匹配之间的任何内容都被视为空白并被忽略(!)以查找差异。您可能希望在正则表达式后附加 |[^[:space:]] 以确保它匹配所有非空白字符。包含换行符的匹配会在换行符处被静默截断(!)。

例如,--word-diff-regex=. 会将每个字符视为一个单词,并相应地逐字符显示差异。

正则表达式也可以通过差异驱动程序或配置选项设置,详见 gitattributes[5]git-config[1]。显式给出它会覆盖任何差异驱动程序或配置设置。差异驱动程序会覆盖配置设置。

--color-words[=<regex>]

相当于 --word-diff=color 加上(如果指定了正则表达式)--word-diff-regex=<regex>

--no-renames

关闭重命名检测,即使配置文件默认开启。

--[no-]rename-empty

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

--check

如果更改引入了冲突标记或空白错误,则发出警告。哪些被视为空白错误由 core.whitespace 配置控制。默认情况下,尾随空白(包括仅由空白组成的行)以及初始缩进中紧跟制表符的空格字符被视为空白错误。如果发现问题,则以非零状态退出。与 --exit-code 不兼容。

--ws-error-highlight=<kind>

在差异的 contextoldnew 行中高亮显示空白错误。多个值用逗号分隔,none 重置以前的值,default 将列表重置为 newallold,new,context 的简写。当未给出此选项,且配置变量 diff.wsErrorHighlight 未设置时,仅高亮显示 new 行中的空白错误。空白错误使用 color.diff.whitespace 着色。

--full-index

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

--binary

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

--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 被视为无限制。

--diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]

只选择已添加 (A)、已复制 (C)、已删除 (D)、已修改 (M)、已重命名 (R)、类型已更改(即普通文件、符号链接、子模块等)(T)、未合并 (U)、未知 (X) 或其配对已损坏 (B) 的文件。可以使用筛选字符的任意组合(包括不使用)。当组合中添加了 * (全部或无)时,如果比较中有任何文件符合其他条件,则选择所有路径;如果没有文件符合其他条件,则不选择任何内容。

此外,这些大写字母可以小写以进行排除。例如,--diff-filter=ad 会排除已添加和已删除的路径。

请注意,并非所有 diff 都能包含所有类型。例如,如果禁用对这些类型的检测,则不会出现已复制和已重命名条目。

-S<string>

查找更改文件中指定 <string> 出现次数(即添加/删除)的差异。供脚本编写者使用。

当您正在寻找一个精确的代码块(如一个结构体),并想知道该块自其首次出现以来的历史时,这很有用:迭代地使用该功能,将预映像中有趣的块反馈回 -S,并持续进行直到您获得该块的第一个版本。

二进制文件也会被搜索。

-G<regex>

查找其补丁文本包含与 <regex> 匹配的添加/删除行的差异。

为了说明 -S<regex> --pickaxe-regex-G<regex> 之间的区别,考虑一个在同一文件中包含以下差异的提交:

+    return frotz(nitfol, two->ptr, 1, 0);
...
-    hit = frotz(nitfol, mf2.ptr, 1, 0);

虽然 git log -G"frotz\(nitfol" 会显示此提交,但 git log -S"frotz\(nitfol" --pickaxe-regex 不会(因为该字符串的出现次数没有改变)。

除非提供了 --text,否则没有 textconv 过滤器的二进制文件的补丁将被忽略。

有关更多信息,请参见 gitdiffcore[7] 中的 *pickaxe* 条目。

--find-object=<object-id>

查找更改指定对象出现次数的差异。类似于 -S,只是参数不同,它不搜索特定字符串,而是搜索特定对象 ID。

该对象可以是 blob 或子模块提交。它隐含了 git-log 中的 -t 选项,以也查找树。

--pickaxe-all

-S-G 找到更改时,显示该变更集中所有更改,而不仅仅是包含 <string> 更改的文件。

--pickaxe-regex

将提供给 -S<string> 视为扩展的 POSIX 正则表达式进行匹配。

-O<orderfile>

控制文件在输出中出现的顺序。这会覆盖 diff.orderFile 配置变量(参见 git-config[1])。要取消 diff.orderFile,请使用 -O/dev/null

输出顺序由 <orderfile> 中全局模式的顺序决定。所有路径名匹配第一个模式的文件首先输出,所有路径名匹配第二个模式(但不匹配第一个)的文件接下来输出,依此类推。所有路径名不匹配任何模式的文件最后输出,如同文件末尾有一个隐式的全匹配模式一样。如果多个路径名具有相同的排名(它们匹配相同的模式但没有更早的模式),则它们相对于彼此的输出顺序是正常的顺序。

<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 命令的使用而发明的,在其他情况下可能不太有用。

-R

交换两个输入;即,显示从索引或磁盘文件到树内容的差异。

--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”)。

--exit-code

使程序以类似于 diff(1) 的代码退出。也就是说,如果存在差异,则以 1 退出,0 表示无差异。

--quiet

禁用程序的所有输出。隐含 --exit-code。禁用外部差异帮助程序的执行,因为它们无法信任其退出代码,即它们的相应配置选项 diff.trustExitCodediff.<driver>.trustExitCode 或环境变量 GIT_EXTERNAL_DIFF_TRUST_EXIT_CODE 为 false。

--ext-diff

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

--no-ext-diff

禁止外部差异驱动程序。

--textconv
--no-textconv

在比较二进制文件时允许(或禁止)运行外部文本转换过滤器。详情请参阅 gitattributes[5]。由于文本转换过滤器通常是单向转换,因此生成的差异适合人工阅读,但无法应用。因此,文本转换过滤器默认仅对 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 中显示为不存在。此选项可以通过 --ita-visible-in-index 恢复。这两个选项都是实验性的,将来可能会被移除。

有关这些通用选项的更详细说明,另请参见 gitdiffcore[7]

-1 --base
-2 --ours
-3 --theirs
-0

分别与“base”版本、“我们分支”或“他们分支”进行差异比较。使用这些选项时,不显示合并条目的差异。

默认是与我们的分支(-2)和已干净解决的路径进行差异比较。可以给出选项 -0 以省略未合并条目的差异输出,只显示“未合并”。

-c
--cc

这会比较阶段 2(我们的分支)、阶段 3(他们的分支)和工作区文件,并输出合并差异,类似于 diff-tree 使用这些标志显示合并提交的方式。

-q

即使文件不存在也保持静默

原始输出格式

git-diff-indexgit-diff-treegit-diff-filesgit diff --raw 的原始输出格式非常相似。

这些命令都比较两组事物;比较的内容有所不同:

git-diff-index <tree-ish>

比较 <tree-ish> 和文件系统上的文件。

git-diff-index --cached <tree-ish>

比较 <tree-ish> 和索引。

git-diff-tree [-r] <tree-ish-1> <tree-ish-2> [<pattern>...]

比较由两个参数命名的树。

git-diff-files [<pattern>...]

比较索引和文件系统上的文件。

git-diff-tree 命令通过打印所比较内容的哈希值来开始其输出。之后,所有命令都为每个更改的文件打印一行输出。

输出行格式如下:

in-place edit  :100644 100644 bcd1234 0123456 M file0
copy-edit      :100644 100644 abcd123 1234567 C68 file1 file2
rename-edit    :100644 100644 abcd123 1234567 R86 file1 file3
create         :000000 100644 0000000 1234567 A file4
delete         :100644 000000 1234567 0000000 D file5
unmerged       :000000 000000 0000000 0000000 U file6

即从左到右:

  1. 一个冒号。

  2. "src" 的模式;如果为创建或未合并,则为 000000。

  3. 一个空格。

  4. "dst" 的模式;如果为删除或未合并,则为 000000。

  5. 一个空格。

  6. "src" 的 SHA1;如果为创建或未合并,则为 0{40}。

  7. 一个空格。

  8. "dst" 的 SHA1;如果为删除、未合并或“工作区与索引不同步”,则为 0{40}。

  9. 一个空格。

  10. 状态,后跟可选的“分数”数字。

  11. 当使用 -z 选项时,一个制表符或一个 NUL。

  12. "src" 的路径。

  13. 当使用 -z 选项时,一个制表符或一个 NUL;仅在 C 或 R 状态下存在。

  14. "dst" 的路径;仅在 C 或 R 状态下存在。

  15. 当使用 -z 选项时,一个 LF 或一个 NUL,用于终止记录。

可能的状态字母是:

  • A:添加文件

  • C:将文件复制为新文件

  • D:删除文件

  • M:文件内容或模式的修改

  • R:文件重命名

  • T:文件类型(常规文件、符号链接或子模块)的更改

  • U:文件未合并(您必须在提交之前完成合并)

  • X:“未知”更改类型(很可能是一个 bug,请报告)

状态字母 CR 总是后跟一个分数(表示移动或复制的源和目标之间的相似度百分比)。状态字母 M 可以后跟一个分数(表示差异度百分比)用于文件重写。

如果文件系统上的文件与索引不同步,则“dst”的 SHA1 显示为全 0。

示例

:100644 100644 5be4a4a 0000000 M file.c

如果没有 -z 选项,带有“不寻常”字符的路径名将按照配置变量 core.quotePath 的解释进行引用(参见 git-config[1])。使用 -z 时,文件名按原样输出,行以 NUL 字节终止。

合并的 diff 格式

git-diff-treegit-diff-filesgit-diff --raw 可以接受 -c--cc 选项,为合并提交也生成差异输出。输出与上述格式的不同之处如下:

  1. 每个父级都有一个冒号

  2. 有更多的“src”模式和“src”SHA1

  3. 状态是每个父级的状态字符的连接

  4. 没有可选的“分数”数字

  5. 以制表符分隔的文件路径名

对于 -c--cc,即使文件在历史的任何一侧被重命名,也只显示目标或最终路径。使用 --combined-all-paths,将显示每个父级中的路径名,然后是合并提交中的路径名。

-c--cc 不带 --combined-all-paths 的示例:

::100644 100644 100644 fabadb8 cc95eb0 4866510 MM	desc.c
::100755 100755 100755 52b7a2d 6d1ac04 d2ac7d7 RM	bar.sh
::100644 100644 100644 e07d6c5 9042e82 ee91881 RR	phooey.c

--combined-all-paths 添加到 -c--cc 时的示例:

::100644 100644 100644 fabadb8 cc95eb0 4866510 MM	desc.c	desc.c	desc.c
::100755 100755 100755 52b7a2d 6d1ac04 d2ac7d7 RM	foo.sh	bar.sh	bar.sh
::100644 100644 100644 e07d6c5 9042e82 ee91881 RR	fooey.c	fuey.c	phooey.c

请注意,combined diff 仅列出从所有父级修改过的文件。

使用 -p 生成补丁文本

运行 git-diff[1]git-log[1]git-show[1]git-diff-index[1]git-diff-tree[1]git-diff-files[1] 并带上 -p 选项会生成补丁文本。您可以通过 GIT_EXTERNAL_DIFFGIT_DIFF_OPTS 环境变量(参见 git[1])以及 diff 属性(参见 gitattributes[5])自定义补丁文本的创建。

-p 选项生成的输出与传统的 diff 格式略有不同:

  1. 它前面是“git diff”头,看起来像这样:

    diff --git a/file1 b/file2

    除非涉及重命名/复制,否则 a/b/ 文件名相同。特别地,即使是创建或删除,也不会使用 /dev/null 来代替 a/b/ 文件名。

    当涉及重命名/复制时,file1file2 分别显示重命名/复制的源文件名称和重命名/复制生成的文件名称。

  2. 后面跟着一个或多个扩展头行:

    old mode <mode>
    new mode <mode>
    deleted file mode <mode>
    new file mode <mode>
    copy from <path>
    copy to <path>
    rename from <path>
    rename to <path>
    similarity index <number>
    dissimilarity index <number>
    index <hash>..<hash> <mode>

    文件模式 <mode> 以 6 位八进制数字打印,包括文件类型和文件权限位。

    扩展头中的路径名不包含 a/b/ 前缀。

    相似度索引是未更改行的百分比,而差异度索引是已更改行的百分比。它是一个四舍五入的整数,后跟百分号。因此,100% 的相似度索引值保留给两个相同的文件,而 100% 的差异度意味着旧文件中的任何一行都没有进入新文件。

    索引行包括更改前后的 blob 对象名称。如果文件模式没有更改,则包含 <mode>;否则,单独的行指示旧模式和新模式。

  3. 包含“不寻常”字符的路径名将按照配置变量 core.quotePath 的解释进行引用(参见 git-config[1])。

  4. 输出中所有 file1 文件都指向提交前的文件,所有 file2 文件都指向提交后的文件。按顺序将每个更改应用于每个文件是不正确的。例如,此补丁将交换 a 和 b

    diff --git a/a b/b
    rename from a
    rename to b
    diff --git a/b b/a
    rename from b
    rename to a
  5. Hunk 头会提及 hunk 应用到的函数名称。有关如何根据特定语言进行调整的详细信息,请参见 gitattributes[5] 中的“定义自定义 hunk-header”。

组合 diff 格式

任何生成差异的命令都可以接受 -c--cc 选项,以便在显示合并时生成合并差异。这是用 git-diff[1]git-show[1] 显示合并时的默认格式。另请注意,您可以向这些命令中的任何一个提供适当的 --diff-merges 选项,以强制生成特定格式的差异。

“组合 diff”格式如下所示:

diff --combined describe.c
index fabadb8,cc95eb0..4866510
--- a/describe.c
+++ b/describe.c
@@@ -98,20 -98,12 +98,20 @@@
	return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1;
  }

- static void describe(char *arg)
 -static void describe(struct commit *cmit, int last_one)
++static void describe(char *arg, int last_one)
  {
 +	unsigned char sha1[20];
 +	struct commit *cmit;
	struct commit_list *list;
	static int initialized = 0;
	struct commit_name *n;

 +	if (get_sha1(arg, sha1) < 0)
 +		usage(describe_usage);
 +	cmit = lookup_commit_reference(sha1);
 +	if (!cmit)
 +		usage(describe_usage);
 +
	if (!initialized) {
		initialized = 1;
		for_each_ref(get_name);
  1. 它前面是“git diff”头,看起来像这样(使用 -c 选项时):

    diff --combined file

    或者像这样(使用 --cc 选项时):

    diff --cc file
  2. 后面跟着一个或多个扩展头行(此示例显示了一个包含两个父级的合并):

    index <hash>,<hash>..<hash>
    mode <mode>,<mode>..<mode>
    new file mode <mode>
    deleted file mode <mode>,<mode>

    mode <mode>,<mode>..<mode> 行仅在至少一个 <mode> 与其余的不同时才出现。带有检测到的内容移动(重命名和复制检测)信息的扩展头部旨在与两个 <tree-ish> 的差异配合使用,不用于组合差异格式。

  3. 后面跟着一个两行的“源文件/目标文件”头:

    --- a/file
    +++ b/file

    类似于传统 unified diff 格式的两行头,/dev/null 用于指示已创建或已删除的文件。

    然而,如果提供了 --combined-all-paths 选项,您将得到一个 N+1 行的“源文件/目标文件”头,而不是两行的“源文件/目标文件”头,其中 N 是合并提交中父级的数量:

    --- a/file
    --- a/file
    --- a/file
    +++ b/file

    如果重命名或复制检测处于活动状态,这种扩展格式会很有用,可以让您查看不同父级中文件的原始名称。

  4. 块头格式已修改,以防止人们意外地将其馈送给 patch -p1。组合差异格式是为审查合并提交更改而创建的,并非用于应用。该更改类似于扩展 索引 头中的更改:

    @@@ <from-file-range> <from-file-range> <to-file-range> @@@

    组合 diff 格式的块头中有(父级数量 + 1)个 @ 字符。

与传统的 统一 差异格式不同,后者显示两个文件 A 和 B,并带有一个单列,其中包含 - (减号——出现在 A 中但在 B 中被删除)、+ (加号——在 A 中缺失但在 B 中添加)或 " " (空格——未更改)前缀,此格式比较两个或更多文件 file1、file2...与一个文件 X,并显示 X 与每个 fileN 的差异。输出行前会添加一个对应每个 fileN 的列,以注明 X 的行与它的不同之处。

列 N 中的 - 字符表示该行出现在 fileN 中,但未出现在结果中。列 N 中的 + 字符表示该行出现在结果中,而 fileN 没有该行(换句话说,从该父级的角度来看,该行是添加的)。

在上述示例输出中,函数签名从两个文件都已更改(因此从 file1 和 file2 都有两个 - 删除,以及 ++ 表示添加的一行既未出现在 file1 中也未出现在 file2 中)。此外,其他八行与 file1 相同但未出现在 file2 中(因此以 + 为前缀)。

当由 git diff-tree -c 显示时,它比较合并提交的父级与合并结果(即 file1..fileN 是父级)。当由 git diff-files -c 显示时,它比较两个未解决的合并父级与工作区文件(即 file1 是阶段 2,又称“我们的版本”,file2 是阶段 3,又称“他们的版本”)。

其他 diff 格式

--summary 选项描述了新添加、删除、重命名和复制的文件。--stat 选项将 diffstat(1) 图形添加到输出中。这些选项可以与其他选项(如 -p)组合使用,主要用于人工阅读。

当显示涉及重命名或复制的更改时,--stat 输出会通过合并路径名的公共前缀和后缀来紧凑地格式化路径名。例如,将 arch/i386/Makefile 移动到 arch/x86/Makefile 同时修改 4 行的更改将显示如下:

arch/{i386 => x86}/Makefile    |   4 +--

--numstat 选项提供 diffstat(1) 信息,但旨在便于机器使用。--numstat 输出中的条目如下所示:

1	2	README
3	1	arch/{i386 => x86}/Makefile

即从左到右:

  1. 添加的行数;

  2. 一个制表符;

  3. 删除的行数;

  4. 一个制表符;

  5. 路径名(可能包含重命名/复制信息);

  6. 一个换行符。

-z 输出选项生效时,输出格式如下:

1	2	README NUL
3	1	NUL arch/i386/Makefile NUL arch/x86/Makefile NUL

即:

  1. 添加的行数;

  2. 一个制表符;

  3. 删除的行数;

  4. 一个制表符;

  5. 一个 NUL(仅在重命名/复制时存在);

  6. 原始映像中的路径名;

  7. 一个 NUL(仅在重命名/复制时存在);

  8. 后映像中的路径名(仅在重命名/复制时存在);

  9. 一个 NUL。

重命名情况下,预映像路径之前的额外 NUL 是为了让读取输出的脚本在不预读的情况下就能判断当前正在读取的记录是单路径记录还是重命名/复制记录。读取添加和删除的行后,读取到 NUL 将得到路径名,但如果它是 NUL,则记录将显示两个路径。

GIT

Git[1] 套件的一部分

scroll-to-top