git-diff-index

原文: https://git-scm.com/docs/git-diff-index

名称

git-diff-index - 将树与工作树或索引进行比较

概要

  1. git diff-index [-m] [--cached] [<common diff options>] <tree-ish> [<path>…​]

描述

将树对象中找到的blob的内容和模式与工作树中相应的跟踪文件或索引中的相应路径进行比较。当< path>存在参数,仅比较与这些模式匹配的路径。否则,将比较所有跟踪的文件。

OPTIONS

  1. -p
  1. -u
  1. --patch

生成补丁(请参阅生成补丁的部分)。

  1. -s
  1. --no-patch

抑制差异输出。对于git show等默认显示补丁的命令,或取消--patch的效果很有用。

  1. -U<n>
  1. --unified=<n>

用< n>生成差异。上下文而不是通常的三行。意味着-p

  1. --raw

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

  1. --patch-with-raw

-p --raw的同义词。

  1. --indent-heuristic

启用改变差异块边界的启发式以使补丁更易于阅读。这是默认值。

  1. --no-indent-heuristic

禁用缩进启发式。

  1. --minimal

花些额外的时间来确保产生尽可能小的差异。

  1. --patience

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

  1. --histogram

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

  1. --anchored=<text>

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

可以多次指定此选项。

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

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

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

  1. default, myers

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

  1. minimal

花些额外的时间来确保产生尽可能小的差异。

  1. patience

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

  1. histogram

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

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

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

生成diffstat。默认情况下,文件名部分将使用必要的空间,图形部分的其余部分将使用。最大宽度默认为终端宽度,如果未连接到终端,则为80列,并且可以被&lt;width&gt;覆盖。可以通过在逗号后面给出另一个宽度&lt;name-width&gt;来限制文件名部分的宽度。可以使用--stat-graph-width=&lt;width&gt;(影响生成统计图的所有命令)或设置diff.statGraphWidth=&lt;width&gt;(不影响git format-patch)来限制图形部分的宽度。通过给出第三个参数&lt;count&gt;,可以将输出限制为第一个&lt;count&gt;行,如果有更多,则可以将...限制为...

也可以使用--stat-width=&lt;width&gt;--stat-name-width=&lt;name-width&gt;--stat-count=&lt;count&gt;单独设置这些参数。

  1. --compact-summary

输出扩展标题信息的精简摘要,例如文件创建或删除(“新”或“消失”,如果是符号链接,则可选“+ l”)和模式更改(“+ x”或“-x”用于添加或删除diffstat中的可执行位)。信息放在文件名部分和图形部分之间。意味着--stat

  1. --numstat

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

  1. --shortstat

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

  1. --dirstat[=<param1,param2,…​>]

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

  1. changes

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

  1. lines

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

  1. files

通过计算更改的文件数来计算dirstat数。在dirstat分析中,每个更改的文件都相同。这是计算上最便宜的--dirstat行为,因为它根本不需要查看文件内容。

  1. cumulative

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

  1. <limit>

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

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

  1. --summary

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

  1. --patch-with-stat

-p --stat的同义词。

  1. -z

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

如果没有此选项,则会引用具有“异常”字符的路径名,如配置变量core.quotePath所述(参见 git-config [1] )。

  1. --name-only

仅显示已更改文件的名称。

  1. --name-status

仅显示已更改文件的名称和状态。有关状态字母的含义,请参阅--diff-filter选项的说明。

  1. --submodule[=<format>]

指定子模块的差异如何显示。指定--submodule=short时,使用格式。此格式仅显示范围开头和结尾的提交名称。指定--submodule--submodule=log时,使用 log 格式。此格式列出 git-submodule [1] summary等范围内的提交。指定--submodule=diff时,使用 diff 格式。此格式显示提交范围之间子模块内容更改的内联差异。如果未设置配置选项,则默认为diff.submodule格式。

  1. --color[=<when>]

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

  1. --no-color

关掉彩色差异。它与--color=never相同。

  1. --color-moved[=<mode>]

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

  1. no

移动的线条不会突出显示。

  1. default

zebra的同义词。这可能会在未来转变为更明智的模式。

  1. plain

在一个位置添加并在另一个位置删除的任何行都将使用 color.diff.newMoved 进行着色。类似地, color.diff.oldMoved 将用于在diff中的其他位置添加的已删除行。此模式选择任何已移动的行,但在检查中确定是否在没有置换的情况下移动了代码块时,它不是很有用。

  1. blocks

贪婪地检测至少20个字母数字字符的移动文本块。使用 color.diff。{old,new} Moved 颜色绘制检测到的块。相邻的街区不能分开。

  1. zebra

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

  1. dimmed-zebra

zebra 类似,但执行了移动代码的无趣部分的额外调暗。两个相邻街区的边界线被认为是有趣的,其余的是无趣的。 dimmed_zebra是不推荐使用的同义词。

  1. --no-color-moved

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

  1. --color-moved-ws=<modes>

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

  1. no

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

  1. ignore-space-at-eol

忽略EOL中的空白更改。

  1. ignore-space-change

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

  1. ignore-all-space

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

  1. allow-indentation-change

最初忽略移动检测中的任何空格,然后如果每行的空白变化相同,则仅将移动的代码块分组到块中。这与其他模式不兼容。

  1. --no-color-moved-ws

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

  1. --word-diff[=<mode>]

使用< mode>显示单词diff。划定改变的单词。默认情况下,单词由空格分隔;见下面的--word-diff-regex。 <模式>默认为 plain ,必须是以下之一:

  1. color

仅使用颜色突出显示更改的单词。意味着--color

  1. plain

将单词显示为[-removed-]{+added+}。如果它们出现在输入中,则不会尝试转义分隔符,因此输出可能不明确。

  1. porcelain

使用特殊的基于行的格式用于脚本使用。添加/删除/未更改的运行以通常的统一diff格式打印,从行开头的+ / - /`字符开始并延伸到行尾。输入中的换行符由其自身行上的波浪号~`表示。

  1. none

再次禁用字差异。

请注意,尽管第一个模式的名称,但如果启用了颜色,则使用颜色突出显示所有模式中已更改的部分。

  1. --word-diff-regex=<regex>

使用< regex>决定一个单词是什么,而不是将非空格的运行视为一个单词。除非已经启用,否则还暗示--word-diff

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

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

正则表达式也可以通过diff驱动程序或配置选项设置,参见 gitattributes [5]git-config [1] 。明确地覆盖任何差异驱动程序或配置设置。 Diff驱动程序覆盖配置设置。

  1. --color-words[=<regex>]

相当于--word-diff=color加(如果指定了正则表达式)--word-diff-regex=&lt;regex&gt;

  1. --no-renames

关闭重命名检测,即使配置文件提供默认值也是如此。

  1. --check

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

  1. --ws-error-highlight=<kind>

突出显示差异的contextoldnew行中的空白错误。多个值用逗号分隔,none重置先前的值,default将列表重置为newallold,new,context的简写。如果未指定此选项,并且未设置配置变量diff.wsErrorHighlight,则仅突出显示new行中的空白错误。空白错误用color.diff.whitespace着色。

  1. --full-index

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

  1. --binary

--full-index外,还可输出可用git-apply应用的二进制差异。

  1. --abbrev[=<n>]

而不是在diff-raw格式输出和diff-tree标题行中显示完整的40字节十六进制对象名称,而是仅显示部分前缀。这与上面的--full-index选项无关,后者控制diff-patch输出格式。可以使用--abbrev=&lt;n&gt;指定非默认位数。

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

将完整的重写更改分为删除和创建对。这有两个目的:

它影响了一个更改的方式,相当于一个文件的完全重写,而不是一系列的删除和插入混合在一起,只有几行恰好与文本作为上下文匹配,而是作为单个删除所有旧的后跟一个单个插入所有新内容,数字m控制-B选项的这一方面(默认为60%)。 -B/70%指定少于30%的原始文本应保留在结果中,以便Git将其视为完全重写(即,否则生成的修补程序将是一系列删除和插入与上下文行混合在一起)。

当与-M一起使用时,完全重写的文件也被视为重命名的源(通常-M只考虑作为重命名源消失的文件),并且数字n控制 - 的这方面 - B选项(默认为50%)。 -B20%指定添加和删除的更改与文件大小的20%或更多相比,有资格被选为可能的重命名源到另一个文件。

  1. -M[<n>]
  1. --find-renames[=<n>]

检测重命名。如果指定了n,则它是相似性指数的阈值(即与文件大小相比的添加/删除量)。例如,-M90%表示如果超过90%的文件未更改,Git应将删除/添加对视为重命名。如果没有%符号,则该数字将作为分数读取,并在其前面加上小数点。即,-M5变为0.5,因此与-M50%相同。同样,-M05-M5%相同。要将检测限制为精确重命名,请使用-M100%。默认相似性指数为50%。

  1. -C[<n>]
  1. --find-copies[=<n>]

检测副本以及重命名。另见--find-copies-harder。如果指定了n,则其含义与-M&lt;n&gt;的含义相同。

  1. --find-copies-harder

出于性能原因,默认情况下,仅当在同一变更集中修改了副本的原始文件时,-C选项才会查找副本。此标志使命令检查未修改的文件作为副本源的候选者。对于大型项目来说,这是一项非常昂贵的操作,因此请谨慎使用。提供多个-C选项具有相同的效果。

  1. -D
  1. --irreversible-delete

省略删除的原像,即只打印标题而不打印原像和/dev/null之间的差异。得到的贴片不适用于patchgit apply;这仅适用于那些希望在更改后专注于审阅文本的人。此外,输出显然缺乏足够的信息来反向应用这样的补丁,甚至手动,因此选项的名称。

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

  1. -l<num>

-M-C选项需要O(n ^ 2)处理时间,其中n是潜在的重命名/复制目标的数量。如果重命名/复制目标的数量超过指定的数量,此选项可防止重命名/复制检测运行。

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

仅选择已添加(A),复制(C),已删除(D),已修改(M),已重命名(R)的文件,其类型(即常规文件,符号链接,子模块,…)更改(T),未合并(U),未知(X),或已配对破碎(B)。可以使用过滤器字符的任何组合(包括无)。当*(全部或全部)添加到组合中时,如果有任何文件与比较中的其他条件匹配,则选择所有路径;如果没有与其他条件匹配的文件,则不会选择任何内容。

此外,这些大写字母可以降级为排除。例如。 --diff-filter=ad排除添加和删除的路径。

请注意,并非所有差异都可以包含所有类型。例如,从索引到工作树的差异永远不会有添加条目(因为差异中包含的路径集受限于索引中的内容)。同样,如果禁用了对这些类型的检测,则无法显示复制和重命名的条目。

  1. -S<string>

查找改变文件中指定字符串出现次数(即添加/删除)的差异。用于脚本编写者的使用。

当你正在寻找一个确切的代码块(比如一个结构体)时,它很有用,并且想要知道该块首次出现以来的历史:迭代地使用该特征将原始图像中的有趣块反馈回-S,继续前进,直到你获得该块的第一个版本。

也搜索二进制文件。

  1. -G<regex>

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

为了说明-S&lt;regex&gt; --pickaxe-regex-G&lt;regex&gt;之间的区别,请考虑在同一文件中使用以下diff进行提交:

  1. + return !regexec(regexp, two->ptr, 1, &regmatch, 0);
  2. ...
  3. - hit = !regexec(regexp, mf2.ptr, 1, &regmatch, 0);

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

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

有关详细信息,请参阅 gitdiffcore [7] 中的 pickaxe 条目。

  1. --find-object=<object-id>

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

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

  1. --pickaxe-all

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

  1. --pickaxe-regex

对待< string>赋予-S作为扩展的POSIX正则表达式以匹配。

  1. -O<orderfile>

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

输出顺序由< orderfile>中的glob模式的顺序决定。首先输出所有与第一个模式匹配的路径名的文件,然后输出所有与第二个模式(但不是第一个模式)匹配的路径名的文件,依此类推。路径名与任何模式都不匹配的所有文件都是最后输出的,就好像文件末尾有一个隐式匹配所有模式一样。如果多个路径名具有相同的等级(它们匹配相同的模式但没有早期模式),则它们相对于彼此的输出顺序是正常顺序。

< orderfile>解析如下:

  • 空行被忽略,因此可以将它们用作分隔符以提高可读性。

  • 以哈希(“#”)开头的行将被忽略,因此它们可用于注释。如果以散列开头,则将反斜杠(“\”)添加到模式的开头。

  • 每个其他行包含一个模式。

模式与没有FNM_PATHNAME标志的fnmatch(3)使用的模式具有相同的语法和语义,但如果删除任意数量的最终路径名组件与模式匹配,则路径名也匹配模式。例如,模式“foo*bar”匹配“fooasdfbar”和“foo/bar/baz/asdf”而不匹配“foobarx”。

  1. -R

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

  1. --relative[=<path>]

从项目的子目录运行时,可以告诉它排除目录外的更改并使用此选项显示相对于它的路径名。当您不在子目录中时(例如,在裸存储库中),您可以通过给出< path>来命名哪个子目录以使输出相对。作为一个论点。

  1. -a
  1. --text

将所有文件视为文本。

  1. --ignore-cr-at-eol

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

  1. --ignore-space-at-eol

忽略EOL中的空白更改。

  1. -b
  1. --ignore-space-change

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

  1. -w
  1. --ignore-all-space

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

  1. --ignore-blank-lines

忽略其行全部为空的更改。

  1. --inter-hunk-context=<lines>

显示差异之间的上下文,直到指定的行数,从而融合彼此接近的帅哥。如果未设置配置选项,则默认为diff.interHunkContext或0。

  1. -W
  1. --function-context

显示整个周围的变化功能。

  1. --exit-code

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

  1. --quiet

禁用程序的所有输出。意味着--exit-code

  1. --ext-diff

允许执行外部diff助手。如果使用 gitattributes [5] 设置外部差异驱动程序,则需要将此选项与 git-log [1] 和朋友一起使用。

  1. --no-ext-diff

禁止外部差异驱动程序。

  1. --textconv
  1. --no-textconv

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

  1. --ignore-submodules[=<when>]

忽略差异生成中子模块的更改。 <当>可以是“none”,“untracked”,“dirty”或“all”,这是默认值。使用“none”时,如果子模块包含未跟踪或修改的文件,或者其HEAD与超级项目中记录的提交不同,则可以使用“无”来修改子模块,并可用于覆盖ignore 选项的任何设置git-config [1]gitmodules [5] 。当使用“未跟踪”时,如果子模块仅包含未跟踪的内容(但仍会扫描修改的内容),则子模块不会被视为脏。使用“脏”忽略对子模块工作树的所有更改,仅显示存储在超级项目中的提交的更改(这是1.7.0之前的行为)。使用“all”隐藏子模块的所有更改。

  1. --src-prefix=<prefix>

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

  1. --dst-prefix=<prefix>

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

  1. --no-prefix

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

  1. --line-prefix=<prefix>

为每行输出预先附加前缀。

  1. --ita-invisible-in-index

默认情况下,“git add -N”添加的条目在“git diff”中显示为现有空文件,在“git diff —cached”中显示为新文件。此选项使条目在“git diff”中显示为新文件,在“git diff —cached”中不存在。可以使用--ita-visible-in-index恢复此选项。这两个选项都是实验性的,将来可以删除。

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

  1. <tree-ish>

要反对的树对象的id。

  1. --cached

根本不考虑磁盘上的文件

  1. -m

默认情况下,索引中记录但未签出的文件将报告为已删除。该标志使 git diff-index 表示所有未签出的文件都是最新的。

原始输出格式

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

这些命令都比较了两组东西;比较的不同之处是:

  1. git-diff-index <tree-ish>

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

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

比较< tree-ish>和索引。

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

比较两个参数命名的树。

  1. git-diff-files [<pattern>…​]

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

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

输出行以这种方式格式化:

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

也就是说,从左到右:

  1. 一个冒号。

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

  3. 空间。

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

  5. 空间。

  6. sha1为“src”; 0 {40}如果创建或未合并。

  7. 空间。

  8. sha1为“dst”; 0 {40}如果创建,未合并或“查看工作树”。

  9. 空间。

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

  11. 使用-z选项时的选项卡或NUL。

  12. “src”的路径

  13. 使用-z选项时的选项卡或NUL;仅适用于C或R.

  14. “dst”的路径;仅适用于C或R.

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

可能的状态字母是:

  • 答:添加文件

  • C:将文件复制到新文件中

  • D:删除文件

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

  • R:重命名文件

  • T:更改文件类型

  • U:文件已取消合并(您必须先完成合并才能提交)

  • X:“未知”更改类型(最有可能是错误,请报告)

状态字母C和R后面总是跟一个分数(表示移动或复制的源和目标之间的相似性百分比)。状态字母M之后可以是文件重写的分数(表示不相似的百分比)。

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

例:

  1. :100644 100644 5be4a4a 0000000 M file.c

如果没有-z选项,则会引用具有“异常”字符的路径名,如配置变量core.quotePath所述(参见 git-config [1] )。使用-z,文件名逐字输出,行以NUL字节终止。

用于合并的diff格式

“git-diff-tree”,“git-diff-files”和“git-diff —raw”可以使用-c--cc选项为合并提交生成diff输出。输出与上述格式的不同之处如下:

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

  2. 还有更多“src”模式和“src”sha1

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

  4. 没有可选的“得分”号码

  5. 单路径,仅适用于“dst”

例:

  1. ::100644 100644 100644 fabadb8 cc95eb0 4866510 MM describe.c

请注意,组合diff 仅列出从所有父项修改的文件。

使用-p生成补丁

当“git-diff-index”,“git-diff-tree”或“git-diff-files”使用-p选项运行时,“git diff”不带--raw选项或“git log”使用“-p”选项,它们不会产生上述输出;相反,他们生成一个补丁文件。您可以通过GIT_EXTERNAL_DIFFGIT_DIFF_OPTS环境变量自定义此类修补程序的创建。

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

  1. 它前面有一个“git diff”标题,如下所示:

    1. diff --git a/file1 b/file2

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

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

  2. 它后跟一个或多个扩展标题行:

    1. old mode &lt;mode&gt;
    2. new mode &lt;mode&gt;
    3. deleted file mode &lt;mode&gt;
    4. new file mode &lt;mode&gt;
    5. copy from &lt;path&gt;
    6. copy to &lt;path&gt;
    7. rename from &lt;path&gt;
    8. rename to &lt;path&gt;
    9. similarity index &lt;number&gt;
    10. dissimilarity index &lt;number&gt;
    11. index &lt;hash&gt;..&lt;hash&gt; &lt;mode&gt;

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

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

    相似性指数是未更改行的百分比,相异性指数是更改行的百分比。它是一个向下舍入的整数,后跟一个百分号。因此,100%的相似性索引值保留用于两个相等的文件,而100%的相异性意味着旧文件中的任何行都不会成为新文件。

    索引行包括更改前后的SHA-1校验和。 <模式>如果文件模式没有改变,则包括在内;否则,单独的行表示旧模式和新模式。

  3. 具有“异常”字符的路径名被引用,如配置变量core.quotePath所述(参见 git-config [1] )。

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

    1. diff --git a/a b/b
    2. rename from a
    3. rename to b
    4. diff --git a/b b/a
    5. rename from b
    6. rename to a

组合差异格式

在显示合并时,任何差异生成命令都可以使用-c--cc选项生成组合差异。当显示与 git-diff [1]git-show [1] 的合并时,这是默认格式。另请注意,您可以为这些命令中的任何一个提供-m选项,以强制使用合并的各个父项生成差异。

组合diff 格式如下所示:

  1. diff --combined describe.c
  2. index fabadb8,cc95eb0..4866510
  3. --- a/describe.c
  4. +++ b/describe.c
  5. @@@ -98,20 -98,12 +98,20 @@@
  6. return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1;
  7. }
  8. - static void describe(char *arg)
  9. -static void describe(struct commit *cmit, int last_one)
  10. ++static void describe(char *arg, int last_one)
  11. {
  12. + unsigned char sha1[20];
  13. + struct commit *cmit;
  14. struct commit_list *list;
  15. static int initialized = 0;
  16. struct commit_name *n;
  17. + if (get_sha1(arg, sha1) < 0)
  18. + usage(describe_usage);
  19. + cmit = lookup_commit_reference(sha1);
  20. + if (!cmit)
  21. + usage(describe_usage);
  22. +
  23. if (!initialized) {
  24. initialized = 1;
  25. for_each_ref(get_name);
  1. 它前面有一个“git diff”标题,看起来像这样(当使用-c选项时):

    1. diff --combined file

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

    1. diff --cc file
  2. 它后跟一个或多个扩展标题行(此示例显示了与两个父项的合并):

    1. index &lt;hash&gt;,&lt;hash&gt;..&lt;hash&gt;
    2. mode &lt;mode&gt;,&lt;mode&gt;..&lt;mode&gt;
    3. new file mode &lt;mode&gt;
    4. deleted file mode &lt;mode&gt;,&lt;mode&gt;

    只有当< mode>中的至少一个出现时,mode &lt;mode&gt;,&lt;mode&gt;..&lt;mode&gt;行才会出现。与其他人不同。具有关于检测到的内容移动(重命名和复制检测)的信息的扩展标题被设计为与两个< tree-ish>的差异一起工作。并且不会被组合diff格式使用。

  3. 接下来是两行的文件/文件头

    1. --- a/file
    2. +++ b/file

    与传统统一 diff格式的双行标题类似,/dev/null用于表示创建或删除的文件。

  4. 修改了块头格式以防止人们意外地将其馈送到patch -p1。创建组合差异格式用于审查合并提交更改,并不适用于应用。此更改类似于扩展索引标头中的更改:

    1. @@@ &lt;from-file-range&gt; &lt;from-file-range&gt; &lt;to-file-range&gt; @@@

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

与传统的统一差异格式不同,后者显示两个文件A和B,其中一列具有-(减去 - 出现在A中但在B中删除),+(加 - 缺少A但是添加到B)或" "(空格 - 未更改)前缀,此格式将两个或多个文件file1,file2,…与一个文件X进行比较,并显示X与每个文件N的不同之处。每个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又名“他们的版本”)。

其他差异格式

--summary选项描述新添加,删除,重命名和复制的文件。 --stat选项将diffstat(1)图形添加到输出。这些选项可以与其他选项结合使用,例如-p,用于人类消费。

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

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

--numstat选项提供diffstat(1)信息,但设计用于更容易的机器消耗。 --numstat输出中的条目如下所示:

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

也就是说,从左到右:

  1. 添加的行数;

  2. 标签;

  3. 删除的行数;

  4. 标签;

  5. pathname(可能带有重命名/复制信息);

  6. 换行符。

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

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

那是:

  1. 添加的行数;

  2. 标签;

  3. 删除的行数;

  4. 标签;

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

  6. 原像中的路径名;

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

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

  9. 一个NUL。

在重命名的情况下,preimage路径之前的额外NUL是允许读取输出的脚本判断正在读取的当前记录是单路径记录还是重命名/复制记录而无需提前读取。读取添加和删除的行后,读取NUL将产生路径名,但如果是NUL,则记录将显示两个路径。

运营模式

您可以选择是否完全信任索引文件(使用--cached标志)或要求diff逻辑显示任何与stat状态不匹配的文件为“暂时更改”。这两项操作确实非常有用。

缓存模式

如果指定了--cached,则可以询问:

  1. show me the differences between HEAD and the current index
  2. contents (the ones I'd write using 'git write-tree')

例如,假设您已经处理了工作目录,更新了索引中的一些文件并准备提交。你想要确切地看到你将提交什么,而不必编写新的树对象并以这种方式进行比较,为此,你只需要做

  1. git diff-index --cached HEAD

示例:假设我已将commit.c重命名为git-commit.c,并且我已经完成了update-index以使其在索引文件中生效。 git diff-files根本不会显示任何内容,因为索引文件与我的工作目录匹配。但是做一个 git diff-index 会:

  1. torvalds@ppc970:~/git> git diff-index --cached HEAD
  2. -100644 blob 4161aecc6700a2eb579e842af0b7f22b98443f74 commit.c
  3. +100644 blob 4161aecc6700a2eb579e842af0b7f22b98443f74 git-commit.c

你可以很容易地看到以上是重命名。

实际上,git diff-index --cached 应该总是完全等同于实际执行 git写树并进行比较。除了这个,你只想检查你的位置的情况要好得多。

因此,当你问自己“我已经标记了什么以及与之前的树有什么区别”时,做一个git diff-index --cached基本上非常有用。

非缓存模式

“非缓存”模式采用不同的方法,并且可能更有用,因为它的作用不能用 git write-tree + git diff-模拟树。这就是默认模式。非缓存版本会询问以下问题:

  1. show me the differences between HEAD and the currently checked out
  2. tree - index contents _and_ files that aren't up to date

这显然是一个非常有用的问题,因为它告诉你可以提交什么。同样,输出将 git diff-tree -r 输出与tee匹配,但有一个扭曲。

扭曲的是,如果某个文件与索引不匹配,我们就没有后备存储的东西,我们使用神奇的“全零”sha1来表示。所以,假设你已经编辑了kernel/sched.c,但实际上还没有对它进行 git update-index - 没有与新状态相关的“对象”,你得到:

  1. torvalds@ppc970:~/v2.6/linux> git diff-index --abbrev HEAD
  2. :100644 100664 7476bb... 000000... kernel/sched.c

即,它表明树已经改变,kernel/sched.c不是最新的,可能包含新的东西。全零sha1意味着要获得真正的差异,您需要直接查看工作目录中的对象,而不是执行对象到对象的差异。

| 注意 | 与此类型的其他命令一样, git diff-index 实际上根本不查看文件的内容。所以也许kernel/sched.c实际上并没有改变,只是你碰到了它。在任何一种情况下,都需要注意 git update-index 才能使索引同步。 |

| 注意 | 您可以将文件混合显示为“已更新”和“在工作目录中仍然是脏的”。您总是可以告诉哪个文件处于哪个状态,因为“已更新”的文件显示有效的sha1,而“与索引不同步”的文件将始终具有特殊的全零值sha1。 |

GIT

部分 git [1] 套件