Git
简体中文 ▾ Topics ▾ Latest version ▾ git-diff-files last updated in 2.44.0

名称

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

概述

git diff-files [-q] [-0|-1|-2|-3|-c|--cc] [<普通差异选项>] [<路径>…​]

描述

Compares the files in the working tree and the index. When paths are specified, compares only those named paths. Otherwise all entries in the index are compared. The output format is the same as for git diff-index and git diff-tree.

选项

-p
-u
--patch

生成补丁(请参阅 使用选项 -p 生成补丁文本 )。

-s
--no-patch

Suppress all output from the diff machinery. Useful for commands like git show that show the patch by default to squelch their output, or to cancel the effect of options like --patch, --stat earlier on the command line in an alias.

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

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

--output=<文件>

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

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

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

--raw

生成原始格式的差异。 这是默认设置。

--patch-with-raw

-p--raw 的同义词。

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

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

--patch-with-stat

同义词 -p --stat

-z

另外,当给出 --raw--numstat--name-only--name-status 选项时, 不合并路径名,并使用 NUL 作为输出字段终止符。

如果没有这个选项,带 “不常见” 字符的路径名会被引用,正如配置变量 core.quotePath 所解释的那样(参见 git-config[1])。

--name-only

Show only names of changed files. The file names are often encoded in UTF-8. For more information see the discussion about encoding in the git-log[1] manual page.

--name-status

Show only names and status of changed files. See the description of the --diff-filter option on what the status letters mean. Just like --name-only the file names are often encoded in UTF-8.

--submodule[=<格式>]

Specify how differences in submodules are shown. When specifying --submodule=short the short format is used. This format just shows the names of the commits at the beginning and end of the range. When --submodule or --submodule=log is specified, the log format is used. This format lists the commits in the range like git-submodule[1] summary does. When --submodule=diff is specified, the diff format is used. This format shows an inline diff of the changes in the submodule contents between the commit range. Defaults to diff.submodule or the short format if the config option is unset.

--color[=<when>]

Show colored diff. --color (i.e. without =<when>) is the same as --color=always. <when> can be one of always, never, or auto.

--no-color

关掉带彩色显示的差异。 这和 --color=never 相同。

--color-moved[=<模式>]

移动的代码行的颜色不同。 如果没有给出该选项,<模式> 默认为 no 如果没有给定模式选项,则为 zebra。 该模式必须以下其中之一:

no

被移动的行不突出显示。

default

zebra 的同义词。今后可能会改成更合理的模式。

plain

Any line that is added in one location and was removed in another location will be colored with color.diff.newMoved. Similarly color.diff.oldMoved will be used for removed lines that are added somewhere else in the diff. This mode picks up any moved line, but it is not very useful in a review to determine if a block of code was moved without permutation.

blocks

Blocks of moved text of at least 20 alphanumeric characters are detected greedily. The detected blocks are painted using either the color.diff.{old,new}Moved color. Adjacent blocks cannot be told apart.

zebra

在 ‘块’ 模式下检测到移动的文本块。块使用 color.diff.{old,new}Moved 颜色或 color.diff.{old,new}MovedAlternative 颜色。这两种颜色之间的变化表示检测到了新的块。

dimmed-zebra

Similar to zebra, but additional dimming of uninteresting parts of moved code is performed. The bordering lines of two adjacent blocks are considered interesting, the rest is uninteresting. dimmed_zebra is a deprecated synonym.

--no-color-moved

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

--color-moved-ws=<模式>

这将配置在执行 --color-moved 选项的移动检测时如何忽略空格。 这些模式可以通过以逗号分隔的列表给出:

no

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

ignore-space-at-eol

忽略行尾空格的变化。

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.

ignore-all-space

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

allow-indentation-change

在最初移动检测中忽略的任何空格,然后只在每行的空格变化相同的情况下,将移动的代码块归为一个块。这与其他模式是不兼容的。

--no-color-moved-ws

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

--word-diff[=<模式>]

Show a word diff, using the <mode> to delimit changed words. By default, words are delimited by whitespace; see --word-diff-regex below. The <mode> defaults to plain, and must be one of:

color

Highlight changed words using only colors. Implies --color.

plain

Show words as [-removed-] and {+added+}. Makes no attempts to escape the delimiters if they appear in the input, so the output may be ambiguous.

porcelain

Use a special line-based format intended for script consumption. Added/removed/unchanged runs are printed in the usual unified diff format, starting with a +/-/` ` character at the beginning of the line and extending to the end of the line. Newlines in the input are represented by a tilde ~ on a line of its own.

none

再次禁用单词差异模式。

请注意,无论第一个模式的名称是什么,如果启用该选项,将在所有模式中使用颜色,以高亮显示更改的部分。

--word-diff-regex=<正则表达式>

Use <regex> to decide what a word is, instead of considering runs of non-whitespace to be a word. Also implies --word-diff unless it was already enabled.

Every non-overlapping match of the <regex> is considered a word. Anything between these matches is considered whitespace and ignored(!) for the purposes of finding differences. You may want to append |[^[:space:]] to your regular expression to make sure that it matches all non-whitespace characters. A match that contains a newline is silently truncated(!) at the newline.

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

The regex can also be set via a diff driver or configuration option, see gitattributes[5] or git-config[1]. Giving it explicitly overrides any diff driver or configuration setting. Diff drivers override configuration settings.

--color-words[=<正则表达式>]

--word-diff=color 和(如果指明了正则表达式)--word-diff-regex=<正则表达式> 两个选项含义相同。

--no-renames

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

--[no-]rename-empty

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

--check

Warn if changes introduce conflict markers or whitespace errors. What are considered whitespace errors is controlled by core.whitespace configuration. By default, trailing whitespaces (including lines that consist solely of whitespaces) and a space character that is immediately followed by a tab character inside the initial indent of the line are considered whitespace errors. Exits with non-zero status if problems are found. Not compatible with --exit-code.

--ws-error-highlight=<种类>

Highlight whitespace errors in the context, old or new lines of the diff. Multiple values are separated by comma, none resets previous values, default reset the list to new and all is a shorthand for old,new,context. When this option is not given, and the configuration variable diff.wsErrorHighlight is not set, only whitespace errors in new lines are highlighted. The whitespace errors are colored with color.diff.whitespace.

--full-index

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

--binary

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

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

Select only files that are Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R), have their type (i.e. regular file, symlink, submodule, …​) changed (T), are Unmerged (U), are Unknown (X), or have had their pairing Broken (B). Any combination of the filter characters (including none) can be used. When * (All-or-none) is added to the combination, all paths are selected if there is any file that matches other criteria in the comparison; if there is no file that matches other criteria, nothing is selected.

Also, these upper-case letters can be downcased to exclude. E.g. --diff-filter=ad excludes added and deleted paths.

请注意,并非所有差异都能显示所有类型。例如,如果禁用了复制和重命名条目类型的检测,这些条目就不会出现。

-S<string>

Look for differences that change the number of occurrences of the specified string (i.e. addition/deletion) in a file. Intended for the scripter’s use.

当您正在寻找确切的代码块(如结构体),并且想知道该块自首次出现以来的历史记录时,这将非常有用:通过 -S 选项迭代,将原文件中的感兴趣的块显示出,并继续进行,直到获得该块的第一个版本。

二进制文件也会被搜索到。

-G<正则表达式>

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

为了说明 -S<正则表达式> --pickaxe-regex-G<正则表达式> 之间的区别,假设某次提交在同一文件中有以下差异:

+    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=<对象ID>

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

该对象可以是一个 blob 或一个子模块提交。它意味着 git-log 中的 -t 选项也能找到工作树。

--pickaxe-all

当使用 -S-G 选项找到一个更改时,显示该更改集中的所有更改,而不仅仅是显示包含 <string> 更改的文件。

--pickaxe-regex

-S 选项的 <string> 参数当作扩展的 POSIX 正则表达式来匹配。

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

-R

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

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

--exit-code

Make the program exit with codes similar to diff(1). That is, it exits with 1 if there were differences and 0 means no differences.

--quiet

禁用程序的所有输出。暗含 --exit-code

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

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

Diff against the "base" version, "our branch", or "their branch" respectively. With these options, diffs for merged entries are not shown.

The default is to diff against our branch (-2) and the cleanly resolved paths. The option -0 can be given to omit diff output for unmerged entries and just show "Unmerged".

-c
--cc

这将比较第二阶段(我们的分支)、第三阶段(他们的分支)和工作区文件,并输出一个综合的差异,类似于 diff-tree 显示带有这些标志的合并提交。

-q

即使对不存在的文件也保持沉默

原始输出格式

"git-diff-index","git-diff-tree","git-diff-files" 和 "git diff --raw" 的原始输出格式非常相似。

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

git-diff-index <目录树对象>

比较 <目录树对象> 和文件系统上的文件。

git-diff-index --cached <目录树对象>

比较 <目录树对象> 和索引。

git-diff-tree [-r] <目录树对象 1> <目录树对象 2> [<模式>…​]

比较由两个参数传递的目录树。

git-diff-files [<模式>…​]

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

"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. sha1 表示 "dst"(目标文件);0{40} 表示删除、未合并或 “工作目录树与索引不同步”。

  9. 空格。

  10. 状态,在可选值 "score" 之后。

  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:"unknown"(未知)更改类型(可能为错误,请报告)

Status letters C and R are always followed by a score (denoting the percentage of similarity between the source and target of the move or copy). Status letter M may be followed by a score (denoting the percentage of dissimilarity) for file rewrites.

如果文件是文件系统上的新文件,并且与索引不同步,则 <sha1> 将显示为全0。

例如:

:100644 100644 5be4a4a 0000000 M 文件.c

Without the -z option, pathnames with "unusual" characters are quoted as explained for the configuration variable core.quotePath (see git-config[1]). Using -z the filename is output verbatim and the line is terminated by a NUL byte.

合并的差异格式

"git-diff-tree", "git-diff-files" and "git-diff --raw" can take -c or --cc option to generate diff output also for merge commits. The output differs from the format described above in the following way:

  1. 每个父提交都有一个冒号

  2. 有更多的 "src" 文件模式和 "src" sha1

  3. 状态是每个父提交的状态字符的合并

  4. 无可选的分数("score")数字

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

For -c and --cc, only the destination or final path is shown even if the file was renamed on any side of history. With --combined-all-paths, the name of the path in each parent is shown followed by the name of the path in the merge commit.

以下为带 -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 生成补丁文本

Running git-diff[1], git-log[1], git-show[1], git-diff-index[1], git-diff-tree[1], or git-diff-files[1] with the -p option produces patch text. You can customize the creation of patch text via the GIT_EXTERNAL_DIFF and the GIT_DIFF_OPTS environment variables (see git[1]), and the diff attribute (see gitattributes[5]).

-p 选项产生的内容与传统的差异格式略有不同:

  1. 它前面有一个 git diff 头,如下所示:

    diff --git a/file1 b/file2

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

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

  2. 它的后面是一个或多个扩展头信息行:

    old mode <模式>
    new mode <模式>
    deleted file mode <模式>
    new file mode <模式>
    copy from <路径>
    copy to <路径>
    rename from <路径>
    rename to <路径>
    similarity index <数字>
    dissimilarity index <数字>
    index <哈希>..<哈希> <模式>

    文件模式被打印为6位八进制数字,包括文件类型和文件权限位。

    扩展头信息中的路径名称不包括 a/b/ 前缀。

    相似性指数是未改变的行占比,而不相似性指数是改变的行占比。它是四舍五入的整数,后有百分号。因此,100%的相似度指数指为两个文件相等,而 100% 的不相似度意味着入新文件中没有旧文件中的行。

    索引行包括改变前和改变后的 blob 对象名称。如果文件模式没有变化,则包含 <模式>;否则,分别显示新旧模式。

  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. 块头提到了块头所适用的函数的名称。 参见 gitattributes[5] 中的 "定义自定义 hunk-header",以了解如何针对特定语言进行定制。

合并的差异格式

任何生成差异的命令都可以使用 -c-cc 选项,在显示合并时产生一个 "合并差异"。当用 git-diff[1]git-show[1] 显示合并时,这默认格式。还需要注意的是,你可以给这些命令适当的 --diff-merges 选项来强制生成特定格式的差异。

"合并的差异" 的格式如下:

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 <哈希>,<哈希>..<哈希>
    mode <模式>,<模式>..<模式>
    new file mode <模式>
    deleted file mode <模式>,<模式>

    The mode <mode>,<mode>..<mode> line appears only if at least one of the <mode> is different from the rest. Extended headers with information about detected contents movement (renames and copying detection) are designed to work with diff of two <tree-ish> and are not used by combined diff format.

  3. 它的后面是两行源文件/目标文件的头信息

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

    类似于传统的 "统一" 差异格式的双行头,/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> @@@

    块中有(父提交数量+1)@ 字符,用于合并的差异格式。

与传统的 "统一" 差异格式不同,这种格式显示两个文件 A 和 B 的列,其中有 -(减号 — 在 A 中出现,但在 B 中删除),+(加号 — 在 A 中缺少,但在 B 中增加),或 " "(空格 — 不变)前缀,这种格式比较两个或多个文件与一个文件 X,并显示 X 与其中每个文件的差异。文件中的每一个都有一列被前置在输出行中,以指出 X 的行与它的不同之处。

第 N 列中的 - 字符意味着该行出现在文件 N 中,但它没有出现在结果文件中。第 N 列中的 + 字符意味着该行出现在结果文件中,而文件 N 中没有该行(换句话说,从该父提交的角度来看,该行是被添加的)。

在上面的输出示例中,两个文件中的函数签名都被改变了(因此从文件 1 和文件 2 中都有表示删除的 -,而 ++ 表示被添加的一行没有出现在文件 1 或文件 2 中)。另外还有 8 行与文件 1 中的相同,但没有出现在文件 2 中(因此前缀为 +)。

当用 git diff-tree -c 显示时,它将合并提交的父提交文件与合并结果进行比较(即文件 1 …​ 文件 N 是父提交文件)。当用 git diff-files -c 显示时,它将两个未解决的合并父提交文件与工作树文件进行比较(即文件 1 是阶段 2 ,又称 "我们的版本",文件 2 是阶段 3,又称 "他们的版本")。

其他差异格式

The --summary option describes newly added, deleted, renamed and copied files. The --stat option adds diffstat(1) graph to the output. These options can be combined with other options, such as -p, and are meant for human consumption.

When showing a change that involves a rename or a copy, --stat output formats the pathnames compactly by combining common prefix and suffix of the pathnames. For example, a change that moves arch/i386/Makefile to arch/x86/Makefile while modifying 4 lines will be shown like this:

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

The --numstat option gives the diffstat(1) information but is designed for easier machine consumption. An entry in --numstat output looks like this:

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 字符。

The extra NUL before the preimage path in renamed case is to allow scripts that read the output to tell if the current record being read is a single-path record or a rename/copy record without reading ahead. After reading added and deleted lines, reading up to NUL would yield the pathname, but if that is NUL, the record will show two paths.

GIT

属于 git[1] 文档

scroll-to-top