git diff-tree

优质
小牛编辑
125浏览
2023-12-01

名称(Name)

git-diff-tree - 比较通过两个树对象找到的 blob 的内容和模式

概要

git diff-tree [--stdin] [-m] [-s] [-v] [--no-commit-id] [--pretty]              [-t] [-r] [-c | --cc] [--root] [<common diff options>]              <tree-ish> [<tree-ish>] [<path>…]

描述

比较通过两个树对象找到的斑点的内容和模式。

如果只给出一个<tree-ish>,则将提交与其父项进行比较(请参阅下面的--stdin)。

请注意,git diff-tree可以使用封装在提交对象中的树。

选项

-p -u --patch

生成补丁(请参阅生成补丁一节)。

-s --no-patch

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

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

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

--raw

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

--patch-with-raw

-p --raw的同义词。

--indent-heuristic --no-indent-heuristic

这些是为了帮助调试和调整实验启发式(默认情况下是关闭的),这些启发式技术改变了差异边界以使修补程序更易于阅读。

--minimal

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

--patience

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

--histogram

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

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

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

default, myers

基本的贪婪 diff 算法。目前,这是默认设置。

minimal

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

patience

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

histogram

此算法将耐心算法扩展为“支持低出现率的通用元素”。

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

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

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

这些参数也可以单独设置--stat-width=<width>--stat-name-width=<name-width>--stat-count=<count>

--numstat

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

--shortstat

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

--dirstat=<param1,param2,…>

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

changes

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

lines

通过执行常规基于行的差异分析来计算 dirstat 数字,并将删除/添加的行数相加。(对于二进制文件,取而代之的是计算64字节的块,因为二进制文件没有自然的行概念)。这是一种--dirstatchanges行为更为昂贵的行为,但它可以像其他更改一样计算文件中重新排列的行数。结果输出与您从其他--*stat选项中获得的结果一致。

files

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

cumulative

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

<limit>

整数参数指定截断百分比(默认为3%)。输出中不显示贡献小于此百分比的目录。

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

--summary

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

--patch-with-stat

-p --stat的同义词。

-z

--raw--numstat--name-only--name-status已给出,不Munge时间路径名,并使用完全无效的输出字段终止符。

如果没有这个选项,带有“不寻常”字符的路径名将按照配置变量的说明引用core.quotePath(请参阅 git-config [1])。

--name-only

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

--name-status

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

--submodule=<format>

指定如何显示子模块中的差异。指定使用--submodule=shortshort格式时。这种格式只显示范围开始和结束处的提交名称。当--submodule或者--submodule=log被指定时,使用log格式。这种格式列出了像 git-submodule [1] summary那样的提交。当--submodule=diff指定时,使用diff格式。这种格式显示了提交范围内子模块内容变化的内嵌比较。如果配置选项未设置,则默认为diff.submoduleshort格式。

--color=<when>

显示有色差异。--color(即没有=<when>)是一样的--color=always<when>可以是一个alwaysneverauto

--no-color

关闭有色差异。它和--color=never。一样。

--word-diff=<mode>

显示一个单词 diff,使用<mode>分隔已更改的单词。默认情况下,单词由空格分隔; 见--word-diff-regex下文。<mode>默认为plain,并且必须是以下之一:

color

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

川( plain )

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

porcelain

使用专门用于脚本消费的基于行的格式。以通常的统一差异格式打印已添加/已删除/未更改的运行,以行开头处的+/ -/字符开始并延伸至行尾。输入中~的换行符通过它自己的一行代字符表示。

none

再次禁用字差异。

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

--word-diff-regex=<regex>

使用<regex>来决定一个单词是什么,而不是将非空白的运行视为一个单词。也意味着--word-diff除非已经启用。

每个<regex>的非重叠匹配都被视为一个单词。为了找到差异,这些匹配之间的任何内容都被认为是空白并被忽略(!)。你可能想追|[^[:space:]]加到你的正则表达式,以确保它匹配所有非空白字符。包含换行符的匹配在换行符处被无提地截断(!)。

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

正则表达式也可以通过 diff 驱动程序或配置选项来设置,请参阅 gitattributes [5]或 git-config [1]。显式给予它将覆盖任何 diff 驱动程序或配置设置。差异驱动程序覆盖配置设置

--color-words=<regex>

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

--no-renames

关闭重命名检测,即使配置文件提供了默认设置。

--check

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

--ws-error-highlight=<kind>

突出显示空白的错误contextold或者new把差异线。多个值以逗号分隔,none重置以前的值,default将列表重置为newall简写为old,new,context。如果未给出此选项,并且diff.wsErrorHighlight未设置配置变量,则只会new突出显示行中的空白错误。空白错误是彩色的color.diff.whitespace

--full-index

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

--binary

除了--full-index输出可以应用的二进制差异git-apply

--abbrev=<n>

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

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

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

它影响到一种改变的方式,这种改变相当于整个文件的重写,而不是像一系列删除和插入混合在一起,只有几行文本与上下文相匹配,但是作为一个单一的删除旧的一切,随后是一个单次插入所有新事物,并且数字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选项需要为 O(n ^ 2)的处理时间,其中n是/复制目标潜在的重命名的数目。如果重命名/复制目标的数量超过指定的数量,则此选项可防止重命名/复制检测运行。

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

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

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

-S<string>

查找改变文件中指定字符串出现次数(即添加/删除)的差异。旨在供剧本使用。

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

-G<regex>

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

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

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

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

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

--pickaxe-all

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

--pickaxe-regex

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

-O<orderfile>

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

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

按以下方式解析<orderfile>:

  • 空白行被忽略,所以它们可以用作分隔符以提高可读性。
  • 以散列(“ #”)开头的行会被忽略,因此它们可以用于注释。\如果以散列开头,则在模式的开头添加反斜杠(“ ”)。
  • 每隔一行包含一个模式。

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

-R

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

--relative=<path>

从项目的子目录运行时,可以通过此选项告知排除目录外的更改并显示与其相关的路径名。如果不在子目录中(例如,在裸存储库中),可以通过给出<path>作为参数来命名将哪个子目录作为输出的相对位置。

-a --text

将所有文件视为文本。

--ignore-space-at-eol

忽略 EOL 中的空白变化。

-b --ignore-space-change

忽略空白量的变化。这会忽略行结束处的空白,并认为一个或多个空白字符的所有其他序列是等价的。

-w --ignore-all-space

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

--ignore-blank-lines

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

--inter-hunk-context=<lines>

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

-W --function-context

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

--exit-code

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

--quiet

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

--ext-diff

允许执行一个外部比较助手。如果你用 gitattributes [5]设置外部差异驱动程序,你需要在 git-log [1]和朋友中使用这个选项。

--no-ext-diff

禁止外部差异驱动程序。

--textconv --no-textconv

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

--ignore-submodules=<when>

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

--src-prefix=<prefix>

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

--dst-prefix=<prefix>

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

--no-prefix

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

--line-prefix=<prefix>

为每行输出预留一个额外的前缀。

--ita-invisible-in-index

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

有关这些常用选项的更详细的解释,请参阅 gitdiffcore [7]。

<tree-ish>

树对象的 ID。

<path>…

如果提供,结果仅限于匹配其中一个前缀字符串的文件子集。即文件匹配/^<pattern1>|<pattern2>|.../请注意,此参数不提供任何通配符或正则表达式功能。

-r

递归到子树中

-t

显示树本身以及子树。意味着-r。

--root

--root指定时,初始提交将显示为一个大的创建事件。这相当于针对 NULL 树的 diff。

--stdin

--stdin指定时,该命令不会从命令行获取<tree-ish>参数。而是从它的标准输入中读取包含两个<tree>,一个<commit>或<commit>列表的行。(使用一个空格作为分隔符。)

当给出两棵树时,它比较第一棵树和第二棵树。当提交一次提交时,它将提交与其父项进行比较。其余的提交,如果给出,就好像它们是第一次提交的父项一样。

在比较两棵树时,两个树的 ID(用空格分隔并以换行符终止)在差异之前打印。比较提交时,会打印第一个(或唯一)提交的 ID,后跟一个换行符。

下面的标志进一步影响比较提交(但不是树)时的行为。

-m

默认情况下,git diff-tree --stdin不显示合并提交的差异。有了这个标志,它显示了所有父母的承诺不同之处。另见-c

-s

默认情况下,git diff-tree --stdin以机器可读形式(不含-p)或补丁形式(含-p)显示差异。这个输出可以被抑制。这只对-v国旗有用。

-v

这个标志导致git diff-tree --stdin在差异之前也显示提交消息。

--pretty=<format> --format=<format>

在给定的格式漂亮地打印提交日志中的内容,在这里<format>可以是一个onelineshortmediumfullfulleremailrawformat:<string>tformat:<string>。什么时候<format>没有上述情况,并且%placeholder在其中,它的行为就像--pretty=tformat:<format>是给予的一样。

有关每种格式的其他详细信息,请参阅“PRETTY FORMATS”部分。当=<format>零件被省略时,它默认为medium

注意:您可以在存储库配置中指定默认的漂亮格式(请参阅 git-config [1])。

--abbrev-commit

不显示完整的40字节十六进制提交对象名称,只显示部分前缀。非默认位数可以用“--abbrev = <n>”来指定(如果显示,它也会修改差异输出)。

这应该使“--pretty = oneline”对于使用80列终端的人来说更加可读。

--no-abbrev-commit

显示完整的40字节十六进制提交对象名称。这种否定--abbrev-commit和暗示它的选项如“--oneline”。它也覆盖log.abbrevCommit变量。

--oneline

这是一起使用的“--pretty = oneline --abbrev-commit”的缩写。

--encoding=<encoding>

提交对象在其编码头中记录用于日志消息的编码; 这个选项可以用来告诉命令在用户首选的编码中重新编写提交日志消息。对于非管道命令,默认为UTF-8。请注意,如果一个对象声称被编码X并且正在输出X,我们将逐字输出对象; 这意味着原始提交中的无效序列可能会被复制到输出中。

--expand-tabs=<n> --expand-tabs --no-expand-tabs

<n>在输出中显示日志消息之前,执行一个标签扩展(将每个标签替换为足够的空格以填充下一个显示列的倍数)。--expand-tabs是一种短手--expand-tabs=8,并且--no-expand-tabs是一种短手--expand-tabs=0,即禁用选项卡扩展。

默认情况下,突片在相当格式由4个空格(即缩进日志消息扩展medium,这是缺省值,fullfuller)。

--notes=<treeish>

在显示提交日志消息时,显示注释提交的注释(请参阅 git-notes [1])。这是默认的git loggit show并且git whatchanged在没有命令--pretty--format或者--oneline在命令行上给出的选项。

默认情况下,显示的注释来自core.notesRefnotes.displayRef变量(或对应的环境覆盖)中列出的注释引用。有关更多详细信息,请参阅 git-config [1]。

使用可选<treeish>参数,使用树状图来查找要显示的注释。当它开始时,树木可以指定完整的 refname refs/notes/; 当它开始时notes/refs/并且否则refs/notes/以前缀形成ref的全名。

多个 - 注释选项可以结合使用来控制显示哪些笔记。例如:“--notes = foo”将只显示“refs / notes / foo”中的注释; “--notes = foo --notes”将显示来自“refs / notes / foo”和默认音符ref(s)的两个音符。

--no-notes

不要显示笔记。这会取消上述--notes选项,方法是重置从中显示注释的注释列表。选项按照命令行给出的顺序进行解析,因此,例如“--notes --notes = foo --no-notes --notes = bar”将仅显示“refs / notes / bar”中的注释。

--show-notes = <treeish> - 无标准记录

这些选项已被弃用。改为使用上面的 - 注释/ - 无备注选项。

--show-signature

通过签名传递gpg --verify并显示输出来检查签名提交对象的有效性。

--no-commit-id

git diff-tree在适用时输出带有提交 ID 的行。该标志抑制了提交 ID 输出。

-c

这个标志改变了合并提交的显示方式(这意味着它只有在给出一个<tree-ish>命令时才有用--stdin)。它显示了每个父母对合并结果的差异,而不是显示父母和结果之间的成对差异(这是-m选项的作用)。此外,它只列出所有父母修改过的文件。

--cc

该标志以与-c选项类似的方式改变了合并提交补丁的显示方式。它意味着-c-p选项,并进一步压缩修补程序的输出,通过省略父母的内容只有两个变体的不感兴趣的区块,并且合并结果不加修改地挑选其中的一个。当所有的hunks都不感兴趣时,就像在任何其他“空比较”情况下一样,提交本身和提交日志消息也不会显示。

--always

即使 diff 本身为空,也要显示提交本身和提交日志消息。

漂亮的格式

If the commit is a merge, and if the pretty-format is not oneline, email or raw, an additional line is inserted before the Author: line. This line begins with "Merge: " and the sha1s of ancestral commits are printed, separated by spaces. Note that the listed commits may not necessarily be the list of the direct parent commits if you have limited your view of history: for example, if you are only interested in changes related to a certain directory or file.

There are several built-in formats, and you can define additional formats by setting a pretty.<name> config option to either another format name, or a format: string, as described below (see git-config[1]). Here are the details of the built-in formats:

  • oneline<sha1> <title line>

This is designed to be as compact as possible.

  • shortcommit <sha1> Author: <author>

<title line>

  • mediumcommit <sha1> Author: <author> Date: <author date>

<title line>

<full commit message>

  • fullcommit <sha1> Author: <author> Commit: <committer>

<title line>

<full commit message>

  • fullercommit <sha1> Author: <author> AuthorDate: <author date> Commit: <committer> CommitDate: <committer date>

<title line>

<full commit message>

  • emailFrom <sha1> <date> From: <author> Date: <author date> Subject: PATCH <title line>

<full commit message>

  • rawThe raw format shows the entire commit exactly as stored in the commit object. Notably, the SHA-1s are displayed in full, regardless of whether --abbrev or --no-abbrev are used, and parents information show the true parent commits, without taking grafts or history simplification into account. Note that this format affects the way commits are displayed, but not the way the diff is shown e.g. with git log --raw. To get full object names in a raw diff format, use --no-abbrev.
  • format:<string>The format:<string> format allows you to specify which information you want to show. It works a little bit like printf format, with the notable exception that you get a newline with %n instead of \n. E.g, format:"The author of %h was %an, %ar%nThe title was >>%s<<%n" would show something like this: The author of fe6e0ee was Junio C Hamano, 23 hours ago The title was >>t4119: test autocomputing -p<n> for traditional diff input.<<

The placeholders are:

-  `%H`: commit hash
-  `%h`: abbreviated commit hash
-  `%T`: tree hash
-  `%t`: abbreviated tree hash
-  `%P`: parent hashes
-  `%p`: abbreviated parent hashes
-  `%an`: author name
-  `%aN`: author name (respecting .mailmap, see [git-shortlog[1]](git-shortlog) or [git-blame[1]](git-blame))
-  `%ae`: author email
-  `%aE`: author email (respecting .mailmap, see [git-shortlog[1]](git-shortlog) or [git-blame[1]](git-blame))
-  `%ad`: author date (format respects --date= option)
-  `%aD`: author date, RFC2822 style
-  `%ar`: author date, relative
-  `%at`: author date, UNIX timestamp
-  `%ai`: author date, ISO 8601-like format
-  `%aI`: author date, strict ISO 8601 format
-  `%cn`: committer name
-  `%cN`: committer name (respecting .mailmap, see [git-shortlog[1]](git-shortlog) or [git-blame[1]](git-blame))
-  `%ce`: committer email
-  `%cE`: committer email (respecting .mailmap, see [git-shortlog[1]](git-shortlog) or [git-blame[1]](git-blame))
-  `%cd`: committer date (format respects --date= option)
-  `%cD`: committer date, RFC2822 style
-  `%cr`: committer date, relative
-  `%ct`: committer date, UNIX timestamp
-  `%ci`: committer date, ISO 8601-like format
-  `%cI`: committer date, strict ISO 8601 format
-  `%d`: ref names, like the --decorate option of [git-log[1]](git-log)
-  `%D`: ref names without the " (", ")" wrapping.
-  `%e`: encoding
-  `%s`: subject
-  `%f`: sanitized subject line, suitable for a filename
-  `%b`: body
-  `%B`: raw body (unwrapped subject and body)
-  `%N`: commit notes
-  `%GG`: raw verification message from GPG for a signed commit
-  `%G?`: show "G" for a good (valid) signature, "B" for a bad signature, "U" for a good signature with unknown validity, "X" for a good signature that has expired, "Y" for a good signature made by an expired key, "R" for a good signature made by a revoked key, "E" if the signature cannot be checked (e.g. missing key) and "N" for no signature
-  `%GS`: show the name of the signer for a signed commit
-  `%GK`: show the key used to sign a signed commit
-  `%gD`: reflog selector, e.g., `refs/stash@{1}` or `refs/stash@{2 minutes ago`}; the format follows the rules described for the `-g` option. The portion before the `@` is the refname as given on the command line (so `git log -g refs/heads/master` would yield `refs/heads/master@{0}`).
-  `%gd`: shortened reflog selector; same as `%gD`, but the refname portion is shortened for human readability (so `refs/heads/master` becomes just `master`).
-  `%gn`: reflog identity name
-  `%gN`: reflog identity name (respecting .mailmap, see [git-shortlog[1]](git-shortlog) or [git-blame[1]](git-blame))
-  `%ge`: reflog identity email
-  `%gE`: reflog identity email (respecting .mailmap, see [git-shortlog[1]](git-shortlog) or [git-blame[1]](git-blame))
-  `%gs`: reflog subject
-  `%Cred`: switch color to red
-  `%Cgreen`: switch color to green
-  `%Cblue`: switch color to blue
-  `%Creset`: reset color
-  `%C(…)`: color specification, as described under Values in the "CONFIGURATION FILE" section of [git-config[1]](git-config). By default, colors are shown only when enabled for log output (by `color.diff`, `color.ui`, or `--color`, and respecting the `auto` settings of the former if we are going to a terminal). `%C(auto,...)` is accepted as a historical synonym for the default (e.g., `%C(auto,red)`). Specifying `%C(always,...) will show the colors even when color is not otherwise enabled (though consider just using &grave;--color=always` to enable color for the whole output, including this format and anything else git might color). `auto` alone (i.e. `%C(auto)`) will turn on auto coloring on the next placeholders until the color is switched again.
-  `%m`: left (`<`), right (`>`) or boundary (`-`) mark
-  `%n`: newline
-  `%%`: a raw `%`
-  `%x00`: print a byte from a hex code
-  `%w([<w>[,<i1>[,<i2>]]])`: switch line wrapping, like the -w option of [git-shortlog[1]](git-shortlog).
-  `%<(<N>[,trunc|ltrunc|mtrunc])`: make the next placeholder take at least N columns, padding spaces on the right if necessary. Optionally truncate at the beginning (ltrunc), the middle (mtrunc) or the end (trunc) if the output is longer than N columns. Note that truncating only works correctly with N >= 2.
-  `%<|(<N>)`: make the next placeholder take at least until Nth columns, padding spaces on the right if necessary
-  `%>(<N>)`, `%>|(<N>)`: similar to `%<(<N>)`, `%<|(<N>)` respectively, but padding spaces on the left
-  `%>>(<N>)`, `%>>|(<N>)`: similar to `%>(<N>)`, `%>|(<N>)` respectively, except that if the next placeholder takes more spaces than given and there are spaces on its left, use those spaces
-  `%><(<N>)`, `%><|(<N>)`: similar to `% <(<N>)`, `%<|(<N>)` respectively, but padding both sides (i.e. the text is centered)
-  %(trailers): display the trailers of the body as interpreted by [git-interpret-trailers[1]](git-interpret-trailers)

注意

一些占位符可能取决于给修订遍历引擎的其他选项。例如,%g * reflog选项将插入一个空字符串,除非我们正在遍历 reflog 条目(例如,通过git log -g)。如果在命令行中未提供 --decorate,则%d 和%D 占位符将使用“短”修饰格式。

如果+%占位符之后添加(加号),当且仅当占位符展开为非空字符串时,才在扩展之前插入换行符。

如果-%占位符之后添加(减号),则当且仅当占位符展开为空字符串时,才会删除紧接扩展之前的所有连续换行。

如果在%占位符之后添加(空格),当且仅当占位符展开为非空字符串时,才会在扩展之前插入空格。

  • tformat:tformat:格式的操作完全相同format:,不同之处在于它提供了“终结者”的语义,而不是“分隔符”的语义。换句话说,每个提交都附加了消息结束符(通常是一个换行符),而不是放置在条目之间的分隔符。这意味着单行格式的最终条目将以新的行正确终止,就像“在线”格式一样。例如:$ git log -2 --pretty = format:%h 4da45bef \ | perl -pe'$ _。=“ - NO NEWLINE \ n”除非/ \ n /'4da45be 7134973 - 否NEWLINE $ git log -2 --pretty = tformat:%h 4da45bef \ | perl -pe'$ _。=“ - NO NEWLINE \ n”除非/ \ n /'4da45be 7134973

另外,任何无法识别的字符串%都会被解释为在它tformat:前面。例如,这两个是等价的:

$ git log -2 --pretty=tformat:%h 4da45bef $ git log -2 --pretty=%h 4da45bef

限制输出

如果您只对一部分文件(例如某些特定于体系结构的文件)的差异感兴趣,则可以这样做:

git diff-tree -r <tree-ish> <tree-ish> arch/ia64 include/asm-ia64

它只会显示你在这两个目录中发生了什么变化。

或者如果你正在寻找刚刚改变的东西,那就kernel/sched.c去做吧

git diff-tree -r <tree-ish> <tree-ish> kernel/sched.c

它会忽略与其他文件的所有区别。

模式始终是前缀,并且完全匹配。没有通配符。更严格的是,它必须匹配完整的路径组件。即“富”不接foobar.h。“foo”确实匹配,foo/bar.h所以它可以用来命名子目录。

正常使用的一个例子是:

torvalds@ppc970:~/git> git diff-tree --abbrev 5319e4:100664 100664 ac348b... a01513...        git-fsck-objects.c

它告诉你最后一次提交只改变了一个文件(它来自这个文件:

commit 3c6f7ca19ad4043e9e72fa94106f352897e651a8
tree 5319e4d609cdd282069cc4dce33c1db559539b03
parent b4e628ea30d5ab3606119d2ea5caeab141d38df7
author Linus Torvalds <torvalds@ppc970.osdl.org> Sat Apr 9 12:02:30 2005committer Linus Torvalds <torvalds@ppc970.osdl.org> Sat Apr 9 12:02:30 2005Make "git-fsck-objects" print out all the root commits it finds.Once I do the reference tracking, I'll also make it print out all the
HEAD commits it finds, which is even more interesting.

如果你在意)。

原始输出格式

“git-diff-index”,“git-diff-tree”,“git-diff-files”和“git 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 file4delete         :100644 000000 1234567... 0000000... D file5
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. 选项卡或 NUL -z选项时使用。
  12. “src”的路径
  13. 使用选项卡时-z选项卡或 NUL ; 只存在于C或R.
  14. “dst”的路径; 只存在于C或R.
  15. 使用LF或 NUL -z选项时,可以终止记录。

可能的状态字母是:

  • A:添加一个文件
  • C:将文件复制到新文件中
  • D:删除文件
  • M:修改文件的内容或模式
  • R:重命名文件
  • T:改变文件的类型
  • U:文件未合并(必须先完成合并,然后才能提交)
  • X:“未知”更改类型(最可能是一个错误,请报告)

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

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

示例:

:100644 100644 5be4a4...... 000000...... M file.c

如果没有这个-z选项,带有“不寻常”字符的路径名将按照配置变量的说明引用core.quotePath(请参阅 git-config [1])。使用-z文件名是逐字输出的,并且该行由NUL字节终止。

比较格式的合并

"git-diff-tree", "git-diff-files" and "git-diff --raw"可以采取-c--cc选项,也产生差异输出合并提交。输出与上述格式的不同之处在于:

  1. 每个父母都有一个冒号
  2. 还有更多的“src”模式和“src”sha1
  3. 状态是每个父级的连接状态字符
  4. 没有可选的“分数”号码
  5. 单一路径,仅适用于“dst”

示例:

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

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

用-p 生成补丁

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

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

  1. 它前面有一个“git diff”头文件,它看起来像这样:diff --git a / file1 b / file2

a/b/文件名是,除非重命名/副本所涉及的相同。尤其是,即使是创建或删除,/dev/null也可not用于替换文件名a/b/文件名。

当重命名/复制参与,file1file2示出了重命名/复制的源文件的名称和重命名/复制分别产生,该文件的名称。

  1. 它后跟一个或多个扩展标题行:旧模式<mode>新模式<mode>已删除文件模式<mode>新文件模式<mode>从<path>复制到<path>从<path>重命名重命名为<path>相似索引<number>不相似索引<number>索引<hash> .. <hash> <mode>

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

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

相似性指数是未改变的行的百分比,不相似性指数是改变的行的百分比。它是一个向下舍入的整数,后面跟着一个百分号。100%的相似性指数值因此保留给两个相同的文件,而100%相异性意味着来自旧文件的任何行都不会将其转换为新的文件。

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

  1. 带有“不常用”字符的路径名将按照配置变量的说明引用core.quotePath(请参阅git-config [1])。
  2. file1输出中的所有文件在提交之前引用文件,所有file2文件在提交之后引用文件。将每个更改顺序应用于每个文件是不正确的。例如,这个补丁会将a和b:diff --git a / ab / b重命名为重命名为b diff --git a / bb / a将重命名从b重命名为a

结合 diff 格式

任何 diff-generating 命令都可以使用-c--cc选项combined diff在显示合并时生成一个。这是显示与 git-diff [1]或git-show [1]合并时的默认格式。还要注意,您可以-m选择这些命令中的任何一个来强制生成合并的单个父代的差异。

combined 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 - 组合文件

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

diff --cc file

  1. 它后面跟着一个或多个扩展标题行(此示例显示与两个父级合并):index <hash>,<hash> .. <hash> mode <mode>,<mode> .. <mode>新文件模式<mode>删除文件模式<mode>,<mode>

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

  1. 紧接着是两行文件/文件头--- a / file +++ b / file

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

  1. 块头格式被修改以防止人们意外地将其提供给patch -p1。组合的差异格式是为了审查合并提交更改而创建的,并不适用于应用。此更改与扩展index标头中的更改类似:@@@ <from-file-range> <from-file-range> <to-file-range> @@@

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

与传统的unified差异格式不同,该格式显示两个文件 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 aka“我们的版本”,file2为阶段3 aka“他们的版本”)。

其他差异格式

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

当显示涉及重命名或复制的更改时,--stat输出会通过组合路径名的通用前缀和后缀来紧凑地格式化路径名。例如,移动的改变arch/i386/Makefile,以arch/x86/Makefile在修改4线将示出这样的:

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

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

1        2        README3        1        arch/{i386 => x86}/Makefile

也就是说,从左到右:

  1. 增加的行数;
  2. 标签;
  3. 删除的行数;
  4. 标签;
  5. 路径名(可能带有重命名/复制信息);
  6. 一个换行符。

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

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

那是:

  1. 增加的行数;
  2. 标签;
  3. 删除的行数;
  4. 标签;
  5. NUL(只有在重命名/复制时才存在);
  6. preimage 中的路径名;
  7. NUL(只有在重命名/复制时才存在);
  8. postimage中的路径名(只有在重命名/复制时才存在);
  9. NUL。

NUL重命名之前的 preimage 路径之前的额外内容是允许读取输出的脚本判断当前正在读取的记录是单路径记录还是重命名/复制记录,而不提前读取。阅读添加和删除的行后,读取NUL会产生路径名,但如果是这样NUL,该记录将显示两个路径。