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

名称

git-log - 显示提交日志

概述

git log [<options>] [<revision-range>] [[--] <path>…​]

描述

显示提交日志。

列出可以从给定的提交中通过 "父 "链接到达的提交,但不包括可以从前面有"^"的提交中到达的提交。 默认情况下,输出结果是按时间顺序倒置的。

你可以把它看成是一个集合操作。从命令行上给出的任何一个提交中可以到达的提交形成一个集合,然后从这个集合中减去任何一个前面带有'^'的提交。 剩下的提交内容就是命令的输出结果。 其他各种选项和路径参数也可以用来进一步限制结果。

因此,可以执行以下命令:

$ git log foo bar ^baz

意思是 "列出所有可以从’foo’或’bar',但不能从’baz’到达的提交"。

一个特殊的符号 "<提交 1>…​<提交 2>" 可以作为 "^<提交 1> <提交 2>" 的简称。例如,以下两种情况可以互换使用:

$ git log origin..HEAD
$ git log HEAD ^origin

另一个特殊的符号是 "<提交 1>…​<提交 2>",对合并很有用。 由此产生的提交集合是两个操作数之间的对称差。 以下两个命令是等价的:

$ git log A B --not $(git merge-base --all A B)
$ git log A...B

该命令采用适用于 git-rev-list[1] 命令的选项来控制显示的内容和方式,以及适用于 git-diff[1] 命令的选项来控制每次提交引入的更改的显示方式。

选项

--follow

继续列出文件的历史记录,包括重命名之后的情况(仅适用于单个文件)。

--no-decorate
--decorate[=short|full|auto|no]

打印显示的任何提交的引用名称。如果指定了 "short",则不会打印引用名称的前缀 "refs/heads/"、"refs/tags/" 和 "refs/remotes/"。如果指定了 "full",将打印完整的引用名称(包括前缀)。如果指定了 "auto",则如果输出是发送到终端,则显示引用名称,就如同指定了"short"一样,否则不显示引用名称。选项 --decorate--decorate=short 的简写。如果配置了 log.decorate 的配置值,默认为配置值,否则为 "auto"。

--decorate-refs=<pattern>
--decorate-refs-exclude=<pattern>

对于每个候选引用,在以下情况下不要将其用于装饰(decorate):若它与`--decorate-refs-exclude`指定的任何模式匹配,或者若它不与`--decorate-refs`指定的任何模式匹配。配置选项`log.excludeDecoration`允许从装饰中排除引用,但是在`log.excludeDecoration`中的匹配项将被`--decorate-refs`模式中的显式指定所覆盖。

如果没有给出这些选项或配置设置中的任何一个,那么如果引用与 HEADrefs/heads/refs/remotes/refs/stash/refs/tags/ 匹配,则使用引用作为装饰。

--clear-decorations

当指定了该选项时,它会清除所有先前的 --decorate-refs--decorate-refs-exclude 选项,并放宽默认的装饰过滤器以包括所有引用。如果配置值 log.initialDecorationSet 设置为 all,则假定使用此选项。

--source

打印出通过命令行给定的引用名称,以便触及每个提交。

--[no-]mailmap
--[no-]use-mailmap

使用 mailmap 文件将作者和提交者的名称和电子邮件地址映射到规范的真实名称和电子邮件地址。请参阅 git-shortlog[1]

--full-diff

如果不使用此标志, git log -p <path>... 将显示与指定路径相关的提交,并显示关于相同指定路径的差异。使用此标志,将显示与指定路径相关的提交的完整差异;这意味着 "<path>…​" 将仅限定提交,并不限定这些提交的差异。

请注意,这会影响所有基于差异的输出类型。例如:由 --stat 等产生的输出。

--log-size

在每个提交的输出中包含一行 ``log size <number>"" ,其中 <number> 是该提交消息的字节长度。旨在通过允许工具预先分配空间,加快从 git log 输出中读取日志消息的工具的速度。

-L<起始>,<结束>:<文件>
-L :<函数名称>:<文件>

追踪由 <起始>,<结束> 给出的行的范围,或由函数名称重合词 <函数名称> 给出的行的演变,在 <文件>'中 。你不能给出任何路径规范限制条件。 目前这只限于从一个修订版开始的行走,也就是说,你只能给出零或一个正的修订版参数,而且 '<起始><结束>(或 <函数名称>)必须存在于起始修订版中。 你可以多次指定这个选项。包含 --patch 选项。 补丁输出可以用 --no-patch 来抑制,但其他差异格式(即 --raw--numstat--shortstat--dirstat--summary--name-only--name-status--check)目前没有实现。

<开始><结束> 可以采取这些形式之一:

  • 数目

    如果'<开始>'或'<结束>'是一个数字,它指定了一个绝对行数(行数从1开始计算)。

  • /正则表达式/

    这种形式将使用与给定的 POSIX 正则表达式匹配的第一行。如果 <start> 是一个重词,它将从前一个 -L 范围的末尾开始搜索,如果有的话,则从文件的开始。 如果 <start>^/regex/,它将从文件的开始搜索。 如果 <end> 是一个正则表达式,它将从 <start> 所给的行开始搜索。

  • +offset或-offset

    这只对'<end>'有效,将指定'<start>'所给的行前或行后的数量。

如果 :<funcname> 代替了 <start><end> ,它是一个正则表达式,表示从第一个匹配 <funcname> 的 funcname 行开始,直到下一个 funcname 行的范围。:<funcname> 从上一个 -L 范围的末尾开始搜索,如果有的话,则从文件的开始搜索。^:<funcname>`从文件的开始搜索。函数名的确定方式与 `git diff 确定补丁组头的方式相同(见 gitattributes[5] 中的’定义自定义组头')。

<revision-range>

仅显示指定修订范围内的提交。当没有指定 <revision-range> 时,默认为 HEAD(即导致当前提交的整个历史记录)。origin..HEAD 指定从当前提交(即 HEAD )可达的所有提交,但不包括从 origin 可达的提交。有关拼写 <revision-range> 的完整列表,请参阅 gitrevisions[7] 的 "Specifying Ranges" 部分。

[--] <path>…​

只显示那些足以解释符合指定路径的文件是如何形成的提交。 有关细节和其他简化模式,请参见下面的’历史简化'。

当出现混淆时,路径可能需要以`--`为前缀,以便将其与选项或修订范围分开。

承诺限制

除了使用描述中解释的特殊符号指定应列出的提交范围,还可以应用额外的提交限制。

使用更多的选项通常会进一步限制输出(例如,--since=<date1>`限制在比<date1>新的提交,与--grep=<pattern>一起使用会进一步限制在日志信息中有一行符合<pattern>`的提交),除非另有说明。

请注意,这些都是在提交排序和格式化选项之前应用的,如 --reverse

-<数>
-n <数量>
--max-count=<数量>

限制输出的提交数量。

--skip=<数量>

在开始显示提交输出之前,跳过’数’的提交。

--since=<日期>
--after=<日期>

显示比某一特定日期更近的提交。

--since-as-filter=<日期>

显示所有比指定日期更近的提交。这将访问该范围内的所有提交,而不是停在第一个比指定日期更早的提交。

--until=<日期>
--before=<日期>

显示超过特定日期的提交。

--author=<模式>
--committer=<模式>

将提交文件的输出限制在作者/提交人标题行符合指定模式(正则表达式)的文件。 如果有多个`--author=<pattern>,则会选择作者符合任何一个给定模式的提交(对于多个--committer=<pattern>`也是如此)。

--grep-reflog=<模式>

将提交文件的输出限制在有符合指定模式(正则表达式)的reflog条目的提交文件。如果有多个 --grep-reflog,则会选择那些 reflog 信息符合任何指定模式的提交。 除非使用了`--walk-reflogs`,否则使用此选项是错误的。

--grep=<模式>

将提交结果限制在日志信息与指定模式(正则表达式)相匹配的提交。 如果有多个 --grep=<模式>,则会选择那些日志信息与任何指定模式相匹配的提交(但见 --all-match)。

--notes 生效时,笔记中的信息被匹配,就像它是日志信息的一部分。

--all-match

将输出的提交限制在符合所有给定`--grep`的提交,而不是至少符合一个的提交。

--invert-grep

限定输出的提交信息与 `--grep=<模式>`指定的模式不匹配。

-i
--regexp-ignore-case

匹配正则表达式的限制模式,不考虑字母大小写。

--basic-regexp

将限制性模式视为基本的正则表达式;这是默认的。

-E
--extended-regexp

将限制性模式视为扩展的正则表达式,而不是默认的基本正则表达式。

-F
--fixed-strings

将限制性模式视为固定字符串(不要将模式解释为正则表达式)。

-P
--perl-regexp

将限制性模式视为与Perl兼容的正则表达式。

对这些类型的正则表达式的支持是一个可选的编译时依赖。如果Git在编译时没有对它们的支持,提供这个选项将导致它死亡。

--remove-empty

当一个给定的路径从树上消失时停止。

--merges

只打印合并后的提交。这与`--min-parents=2`完全相同。

--no-merges

不打印有一个以上父级的提交。这与`--max-parents=1`完全相同。

--min-parents=<数量>
--max-parents=<数量>
--no-min-parents
--no-max-parents

只显示至少(或最多)有那么多父提交的提交。特别是,--max-parents=1`等同于--no-merges`,--min-parents=2`等同于--merges`。 --max-parents=0`给出所有根提交,--min-parents=3`给出所有章鱼合并。

--no-min-parents--no-max-parents 会再次重置这些限制(为无限制)。 等价形式是 --min-parents=0(任何提交都有 0 个或更多父代)和 --max-parents=-1(负数表示无上限)。

--first-parent

查找要包含的提交时,在看到合并提交时只跟随第一个父提交。 在查看某个特性分支的演变时,该选项可以提供更好的概览,因为合并到特性分支往往只是为了不时地适应上游的更新,而该选项可以让你忽略由合并带来的历史中的单个提交。

这个选项也改变了合并提交的默认差异格式为 first-parent,详见 --diff-merges=first-parent

--exclude-first-parent-only

在寻找要排除的提交(用'^')时,在看到合并提交时只跟随第一个父提交。 考虑到任意的合并都可以成为有效的主题分支变化,这可以用来查找主题分支中从它与远程分支的分歧点开始的变化集合。

--not

反转 ^ 前缀(或无前缀)对后面所有版本说明符的意义,直到下一个 --not。 在 --stdin 之前的命令行中使用时,通过标准输入流传递的修订版本不会受其影响。反之,通过标准输入传递时,命令行上传递的修订版本也不会受其影响。

--all

假设`refs/‘中的所有参考文献,连同`HEAD`一起,在命令行中被列为’<commit>'。

--branches[=<模式>]

假设`refs/heads`中的所有 refs 在命令行中被列为 <commit>。如果给出了'<pattern>',将分支限制在与给定的shell glob相匹配的分支。如果pattern缺少'?*'或'[,则末尾的/*'是暗示的。

--tags[=<模式>]

假设`refs/tags`中的所有参考文献在命令行中被列为'<commit>'。如果给出了'<pattern>',将标签限制在与给定的shell glob相匹配的标签。如果pattern缺少'?*'或'[,则暗示最后的/*'。

--remotes[=<模式>]

假设`refs/remotes`中的所有 refs 在命令行中被列为 <commit>。如果给出了'<pattern>',将远程跟踪分支限制在与给定的shell glob相匹配的分支。 如果pattern缺少'?*'或'[,则末尾的/*'是暗示的。

--glob=<通配符模式>

假设所有与shell glob <glob-pattern>相匹配的refs在命令行中被列为<commit>'。前面的’refs/,如果缺少的话会自动预加。如果模式中缺少?*'或'[,则在结尾处隐含/*'。

--exclude=<通配符模式>

不包括匹配"<glob-pattern>"的参考文献,否则下一个`--all`、--branches--tags--remotes`或--glob`会考虑这些参考文献。重复这个选项可以累积排除模式,直到下一个`----all`、---branches---tags---remotes`或---glob`选项(其他选项或参数不清除累积模式)。

当应用于 --branches--tags--remotes 时,所给出的模式不应以 refs/headsrefs/tagsrefs/remotes 开头;当应用于 --glob--all 选项时,必须以 refs/ 开头。如果要使用尾部的 /*,则必须明确给出。

--exclude-hidden=[fetch|receive|uploadpack]

通过查阅相应的 fetch.hideRefsreceive.hideRefsuploadpack.hideRefs 配置和 transfer.hideRefs 配置(参见 git-config[1]),不要包含会被 git-fetchgit-receive-packgit-upload-pack 隐藏的引用。该选项会影响下一个伪引用选项 --all--glob,并在处理后清除。

--reflog

假设reflogs提到的所有对象都在命令行中被列为`<commit>`。

--alternate-refs

假设所有提到的作为备用仓库的参考提示的对象都列在命令行上。备用资源库是任何资源库,其对象目录在`objects/info/alternates`中指定。 包含的对象集可以通过`core.alternateRefsCommand`等修改。见git-config[1]

--single-worktree

默认情况下,当有多个工作树时,所有工作树都会被以下选项检查(见git-worktree[1]):--all--reflog`和--indexed-objects`。 这个选项强制它们只检查当前的工作树。

--ignore-missing

在看到输入中无效的对象名称时,假装没有给出坏的输入。

--bisect

假设坏的二分法参考文献`refs/bisect/bad`被列出,并且在命令行中假设它后面是`--not`和好的二分法参考文献`refs/bisect/good-*`。

--stdin

除从命令行获取参数外,还可从标准输入读取参数。它接受提交和伪选项,如 --all--glob=。当看到 -- 分隔符时,下面的输入将被视为路径并用于限制结果。通过标准输入读取的 --not 等标志只适用于以相同方式传递的参数,不会影响后续的命令行参数。

--cherry-mark

就像`--cherry-pick`(见下文),但用`=标记同等的提交,而不是省略,用+`标记不同等的提交。

--cherry-pick

当提交的集合有对称差异时,省略任何与 "另一边 "的另一个提交相同的提交。

例如,如果你有两个分支,AB,通常的方法是用`--左—​右`列出其中一边的所有提交(见下面关于`--left-right`选项的描述)。然而,它显示的是从另一个分支中偷梁换柱的提交(例如,'3rd on b' 可能是从分支 A 中偷梁换柱的)。有了这个选项,这样的提交对将从输出中排除。

--left-only
--right-only

只列出对称性差异各自一侧的提交,即只列出那些通过 --left-right 标记的 <>

例如,--cherry-pick --right-only A...B`省略了`B`中那些在`A`中的提交或与`A`中的提交相等的补丁。换句话说,它列出了 "git cherry A B "的 "+"的提交。 更准确地说,--cherry-pick --right-only --no-merges`可以得到准确的列表。

--cherry

--right-only --cherry-mark --no-merges`的同义词;有助于将输出限制在我们这边的提交,并标记那些已经应用到分叉历史的另一边的提交,`git log --cherry upstream...mybranch,类似于`git cherry upstream mybranch`。

-g
--walk-reflogs

不走提交祖先链,而走从最近的提交到更早的提交的reflog条目。 使用这个选项时,你不能指定要排除的提交(也就是说,不能使用'^commit'、'commit1…​commit2’和’commit1/…​commit2’的符号)。

--pretty 格式下,除了 onelinereference (由于明显的原因),这将导致输出有两行额外的信息来自引用日志。 输出中的引用日志代号可以显示为 ref@{Nth}(其中 Nth 是引用日志中的逆序索引)或 ref@{timestamp} (带有该条目的时间戳),取决于一些规则:

  1. 如果起点被指定为`ref@{Nth}`,显示索引格式。

  2. 如果起点被指定为`ref@{now}`,显示时间戳格式。

  3. 如果两者都没有使用,但在命令行中给出了`--date`,则按照`--date`所要求的格式显示时间戳。

  4. 否则,显示索引格式。

在`--pretty=oneline`下,提交信息的前缀是同一行中的这些信息。 这个选项不能与 `--reverse`结合使用。 参见 git-reflog[1]

在`--pretty=reference`下,这些信息将完全不显示。

--merge

在合并失败后,显示触及有冲突的文件且不存在于所有要合并的头的参考文件。

--boundary

输出排除的边界提交。边界提交的前缀是"-"。

简化历史

有时你只对历史的一部分感兴趣,例如修改某个<路径>的提交。但 "历史简化 "有两部分,一部分是选择提交,另一部分是如何做,因为有各种策略来简化历史。

以下选项选择要显示的提交:

<paths>

修改给定<路径>的提交会被选中。

--simplify-by-decoration

被某个分支或标签引用的提交被选中。

请注意,可以显示额外的提交,以提供一个有意义的历史。

以下选项会影响简化的执行方式:

默认模式

将历史简化为解释树的最终状态的最简单的历史。最简单的原因是,如果最终结果相同,它会修剪一些侧枝(即合并具有相同内容的分支)

--show-pulls

包括默认模式下的所有提交,但也包括任何与第一个父分支不相干但与后来的父分支相干的合并提交。这种模式有助于显示 "首次引入 "某个分支的合并提交。

--full-history

与默认模式相同,但不修剪一些历史记录。

--dense

只显示所选的提交,再加上一些才有意义的历史。

--sparse

简化历史中的所有提交都会显示出来。

--simplify-merges

为`--full-history`增加了一个选项,可以从结果的历史中删除一些不必要的合并,因为没有选定的提交对这次合并有贡献。

--ancestry-path[=<提交>]

如果给定了一个要显示的提交范围(例如 提交1..提交2提交2 ^-提交1 ),则只会显示该范围内属于 <提交> 的祖先、<提交> 的后代或 <提交> 本身的提交。 如果没有指定提交,则使用 提交1(范围中排除的部分)作为 <提交>。 可以多次传递;如果是这样,如果某个提交是所给定提交中的任何一个,或者是其中一个提交的祖先或后代,则该提交将被包括在内。

以下是更详细的解释。

假设你指定了 foo 作为 <路径>。 我们将把修改 foo 的提交称为 !TREESAME,其余的称为 TREESAME。 (在为 foo 过滤的差异中,它们看起来分别是不同的和相同的。)

在下文中,我们将始终引用同一个历史实例来说明简化设置之间的差异。 我们假设你在这个提交图中过滤的是一个文件 foo

	  .-A---M---N---O---P---Q
	 /     /   /   /   /   /
	I     B   C   D   E   Y
	 \   /   /   /   /   /
	  `-------------'   X

历史 A---Q 的横线被认为是每次合并的第一个父本。 这些提交是:

  • ‘I`是初始提交,其中`foo`存在,内容是`asdf’,文件`quux`存在,内容是`quux'。初始提交与空树比较,所以`I`是!`TREESAME。

  • 在`A`中,‘foo`只包含`foo’'。

  • `B`包含与`A`相同的变化。 它的合并`M`是微不足道的,因此对所有父类来说是TREESAME。

  • C`没有改变`foo,但是它的合并`N`将其改为`foobar'',所以它与任何父类都不存在TREESAME。

  • ‘D`将`foo`设置为`baz’。它的合并项`O`将`N`和`D`的字符串合并为`foobarbaz';也就是说,它与任何父类都不是TREESAME。

  • ‘E`将`quux`改为`xyzzy’,其合并的`P`将这些字符串合并为`quux xyzzy'。`P’与`O’的关系是TREESAME,但与`E’不是。

  • X`是一个独立的根提交,添加了一个新文件`sideY`修改了它。`Y`与`X`同为TREESAME。它的合并文件`Q`在`P`上添加了`side,`Q`与`P`是同源,但与`Y`不是同源。

rev-list`在历史中倒退,根据是否使用--full-history`和/或父代重写(通过`--parents`或`--children`),包括或排除提交。以下设置是可用的。

默认模式

如果提交的内容与任何父类不相干,则被包括在内(当然这一点可以改变,见下面的`--sparse`)。 如果该提交是一个合并,并且它与一个父类是同源的,则只跟随该父类。 (即使有几个TREESAME父类,也只跟随其中一个。) 否则,跟随所有父类。

这将实现:

	  .-A---N---O
	 /     /   /
	I---------D

请注意,如果有TREESAME父类的话,只遵循TREESAME父类的规则,将`B’完全排除在考虑之外。 `C`是通过`N`考虑的,但也是TREESAME。 根提交是与空树比较的,所以`I`是!!TREESAME。

父/子关系只有在使用 --parents 选项的情况下才能看到,但这并不影响在默认模式下选择的提交,所以我们显示了父行。

--full-history 无父级重写的完整历史记录

这种模式与默认模式有一点不同:总是跟随一个合并的所有父本,即使它与其中一个父本是TREESAME。 即使合并的一方有多个提交被包括在内,这也不意味着合并本身也是如此在这个例子中,我们得到

	I  A  B  N  D  O  P  Q

M 被排除在外,因为它与父母都是TREESAME。 EC 和`B` 都走了,但只有`B` 是 !TREESAME,所以其他的都没有出现。

请注意,如果没有父子重写,其实是不可能谈论提交之间的父子关系的,所以我们显示它们是不相连的。

--full-history 带父级重写功能的全历史记录

普通的提交只有当它们是!TREESAME时才会被包括在内(尽管这一点可以改变,见下面的`--sparse`)。

合并总是被包括在内。 然而,他们的父级列表会被重写。沿着每个父级,修剪掉那些不包括自己的提交。 这样做的结果是

	  .-A---M---N---O---P---Q
	 /     /   /   /   /
	I     B   /   D   /
	 \   /   /   /   /
	  `-------------'

与上面的`--full-history`相比,没有重写。 请注意,E`被修剪掉了,因为它是TREESAME,但是P的父列表被改写为包含`E`的父`I。 同样的情况发生在`C`和`N`,以及`X`、Y`和`Q

除了上述设置外,你还可以改变 TRESAME 是否会影响收录:

--dense

如果不与任何父类有TREESAME关系,则包括走过的承诺。

--sparse

所有走过的提交都包括在内。

请注意,如果没有`--full-history`,这仍然可以简化合并:如果父代之一是TREESAME,我们只跟随这个父代,所以合并的其他方面永远不会被走。

--simplify-merges

首先,按照`--full-history`与父级改写的相同方式建立一个历史图(见上文)。

然后根据以下规则将每个提交的 C 简化为最终历史中的替换 C

  • 将 "C "设为 "C"。

  • 将`C'的每个父类`P'替换成其简化的`P'。 在这个过程中,放弃那些是其他父类的祖先的父类,或者是根部提交TREESAME的空树,并删除重复的父类,但注意不要放弃所有我们是TREESAME的父类。

  • 如果在这次父级改写之后,‘C’`是一个根或合并提交(有0个或>1个父级),一个边界提交,或!TREESAME,那么它将被保留。 否则,它将被替换为其唯一的父类。

通过与 --full-history 选项的父级改写进行比较,可以最好地显示其效果。 这个例子变成了:

	  .-A---M---N---O
	 /     /       /
	I     B       D
	 \   /       /
	  `---------'

注意 NPQ--full-history 的主要区别:

  • N`的父列表中删除了`I,因为它是另一个父`M`的一个祖先。 但是,`N`仍然存在,因为它是!TREESAME。

  • P`的父级列表也同样删除了`I。 然后`P`被完全删除,因为它有一个父本,并且是TREESAME。

  • Q`的父列表中有`Y`简化为`X。然后`X`被删除,因为它是一个TREESAME根。然后`Q`被完全删除,因为它有一个父级,是TREESAME。

还有一种简化模式可用:

--ancestry-path[=<提交>]

将显示的提交限制在<提交>的祖先,或<提交>的后代,或<提交>本身。

作为一个用例,请考虑以下提交历史:

	    D---E-------F
	   /     \       \
	  B---C---G---H---I---J
	 /                     \
	A-------K---------------L--M

有规律的 "D…​M "会计算出作为`M`的祖先的提交集合,但不包括作为`D`的祖先的提交。这对了解`M’的历史在`D’之后发生了什么很有用,也就是说`M’有什么东西是`D’没有的'。这个例子中的结果是所有的提交,除了`A`和`B`(当然还有`D`本身)。

然而,当我们想找出`M’中哪些提交被`D’引入的错误所污染而需要修复时,我们可能只想查看’D…​M’中实际上是`D’的后代的子集,即排除`C’和`K'。这正是`--ancestry-path`选项的作用。应用于’D…​M’范围,它的结果是:

		E-------F
		 \       \
		  G---H---I---J
			       \
				L--M

我们也可以用`--ancestry-path=D`来代替`--ancestry-path`,这在应用于’D…​M’范围时意思相同,只是更加明确。

如果我们感兴趣的是这个范围内的某个主题,以及受该主题影响的所有提交,我们可能只想查看祖先路径中包含该主题的`D…​M`子集。 因此,以`--ancestry-path=H D…​M`为例,会形成以下结果:

		E
		 \
		  G---H---I---J
			       \
				L--M

而`--ancestry-path=K D…​M`会形成以下结果

		K---------------L--M

在讨论另一个选项,`--show-pulls`之前,我们需要创建一个新的历史实例。

用户在查看简化的提交历史时经常遇到的一个问题是,他们知道的对某个文件的修改提交并没有出现在该文件的简史中。让我们演示一个新的例子,并说明`--full-history`和`--simplify-merges`等选项在这种情况下是如何工作的:

	  .-A---M-----C--N---O---P
	 /     / \  \  \/   /   /
	I     B   \  R-'`-Z'   /
	 \   /     \/         /
	  \ /      /\        /
	   `---X--'  `---Y--'

在这个例子中,假设`I`创建了`file.txt`,并被`A`、B`和`X`以不同方式修改。单亲提交的`CZ`和`Y`没有修改`file.txt。合并提交 M`是通过解决合并冲突而产生的,包括了 `A `和 `B `的修改,因此与其中任何一个都不是同源的。然而,合并提交`R`是通过忽略`M`处的`file.txt`的内容,而只采用`X`处的`file.txt`的内容而产生的。因此,`R`与`X`是同源的,但不是`M。最后,创建`N’的自然合并决议是取`file.txt`在`R’的内容,所以`N’与`R`是同源的,但不是`C`。 合并提交的 OP 与它们的第一代父母是同源的,但与它们的第二代父母 Z 和 `Y `则不是同源的。

当使用默认模式时,`N’和`R`都有一个TREESAME父级,所以这些边被展示出来,其他边被忽略。由此产生的历史图是:

	I---X

当使用 --full-history 选项时,Git 会行走每条边。这将发现提交 AB 以及合并 M,但也将揭示合并提交 OP 。通过父级改写,得到的图是:

	  .-A---M--------N---O---P
	 /     / \  \  \/   /   /
	I     B   \  R-'`--'   /
	 \   /     \/         /
	  \ /      /\        /
	   `---X--'  `------'

这里,合并提交 OP 带来了额外的输出,因为它们实际上并没有对 file.txt 做出改变。他们只是合并了一个基于 file.txt 旧版本的主题。这是在使用工作流程的仓库中常见的问题,在工作流程中,许多贡献者并行工作,并沿着一个主干合并他们的主题分支:不相关的合并出现在 --full-history 选项结果中。

当使用`--simplify-merges`选项时,提交的 OP 从结果中消失。这是因为 OP 重写的第二父本可以从它们的第一父本到达。这些边被移除,然后这些提交看起来就像与它们的父类一样的单亲提交。这也发生在提交 N 上,导致历史视图如下:

	  .-A---M--.
	 /     /    \
	I     B      R
	 \   /      /
	  \ /      /
	   `---X--'

在这个视图中,我们看到了所有来自`A`,B`和`X`的重要单亲变化。我们还可以看到仔细解决的合并`M`和不那么仔细解决的合并`R。这些信息通常足以确定为什么`A`和`B`的提交在默认视图中从历史中 "消失 "了。然而,这种方法也有一些问题。

第一个问题是性能。与之前的任何选项不同,--simplify-merges 选项需要在返回一个结果之前走完整个提交历史。这可能使该选项难以用于非常大的仓库。

第二个问题是审计的问题。当许多贡献者在同一个版本库中工作时,哪些合并提交将一个变化引入到一个重要的分支是很重要的。上面有问题的合并`R`不可能是用来合并到一个重要分支的合并提交。相反,`N’是用来将`R’和`X’合并到重要分支的。这个提交可能有关于为什么`X’会覆盖`A’和`B’的修改的信息,在其提交信息中。

--show-pulls

除了在默认历史中显示的提交之外,还要显示每一个与第一个父本不相同但与后来的父本相同的合并提交。

当一个合并提交被 --show-pulls 选项包含时,该合并被视为从另一个分支 “拉取” 来的修改。在这个例子中使用 --show-pulls 选项时(没有其他选项),得到的图是:

	I---X---R---N

这里,合并后的提交`R`和`N`被包括在内,因为它们分别将提交`X`和`R`拉到了基础分支。这些合并是`A`和`B`的提交没有出现在默认历史中的原因。

--show-pulls--simplify-merges 选项配对时,该图包括所有必要的信息:

	  .-A---M--.   N
	 /     /    \ /
	I     B      R
	 \   /      /
	  \ /      /
	   `---X--'

请注意,由于`M`可以从`R`到达,从`N`到`M`的边被简化掉了。然而,`N`仍然作为一个重要的提交出现在历史中,因为它把`R`的修改 "拉 "进了主分支。

--simplify-by-decoration 选项允许你只查看历史拓扑的全貌,省略那些没有被标签引用的提交。 如果 (1) 提交被标签引用,或者 (2) 提交改变了命令行上给出的路径内容,则被标记为 TREESAME(换句话说,按照上述历史简化规则保留)。 所有其他的提交都被标记为 TREESAME(会被简化掉)。

承诺订购

默认情况下,提交的内容是按时间顺序倒序显示的。

--date-order

在显示所有子代之前不显示父代,否则按提交时间戳顺序显示提交。

--author-date-order

在显示所有子代之前不显示父代,否则按作者时间戳顺序显示提交。

--topo-order

在显示所有子代之前不显示父代,并避免显示多行历史交错的提交。

例如,在这样的一个提交历史中:

    ---1----2----4----7
	\	       \
	 3----5----6----8---

其中数字表示提交时间戳的顺序,git rev-list`和带有--date-order`的朋友显示提交的时间戳顺序。8 7 6 5 4 3 2 1.

如果使用`--topo-order`,它们会显示8 6 5 3 7 4 2 1(或8 7 4 2 6 5 3 1);一些较早的提交会显示在较新的提交之前,以避免显示两个平行开发轨道的提交混在一起。

--reverse

以相反的顺序输出选择显示的提交(见上面的提交限制部分)。不能与`--walk-reflogs`结合使用。

对象遍历

这些选项主要是针对Git存储库的打包。

--no-walk[=(sorted|unsorted)]

只显示给定的提交,但不遍历其祖先。 如果指定了范围,这一点就没有影响。如果给了参数 unsorted,提交会按照命令行上的顺序显示。否则(如果 sorted 或者没有给出参数),提交将按照提交时间的倒序显示。 不能与 --graph 选项结合使用。

--do-walk

覆盖之前的 --no-walk

承诺格式化

--pretty[=<格式>]
--format=<格式>

以指定的格式打印提交日志的内容,其中'<format>'可以是’oneline'、shortmediumfullfullerreferenceemailrawformat:<string>'和’tformat:<string>'之一。 当<format>'不是上述任何一种,并且其中有'%placeholder’时,它的作用就像给出'--pretty=tformat:<format>'一样。

参见 "PRETTY FORMATS "部分,了解每种格式的一些额外细节。 当'=<格式>'部分被省略时,它默认为’中等'。

注意:你可以在版本库配置中指定默认的漂亮格式(见git-config[1])。

--abbrev-commit

不要显示完整的40字节的十六进制提交对象名称,而是显示一个前缀,以唯一的方式命名该对象。 "--abbrev=<n>"选项可以用来指定前缀的最小长度(如果显示的话,它也会修改diff输出)。

这应该使"--pretty=oneline "对于使用80列终端的人来说更容易阅读。

--no-abbrev-commit

显示完整的40字节十六进制的提交对象名称。这否定了`--abbrev-commit`,无论是明确的还是由其他选项如"--oneline "暗示的。它还覆盖了`log.abbrevCommit`变量。

--oneline

这是"--pretty=oneline --abbrev-commit "的简写,一起使用。

--encoding=<编码>

提交对象会在其编码头中记录日志信息使用的字符编码;该选项可用于告诉命令以用户偏好的编码重新编码提交日志信息。 对于非底层命令,默认编码为 UTF-8。需要注意的是,如果对象声称以 X 编码,而我们以 X 输出,我们将逐字输出该对象;这意味着原始提交中的无效序列可能会被复制到输出中。同样,如果 iconv(3) 无法转换提交,我们也会静静地逐字输出原始对象。

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

在输出中显示之前,在日志信息中进行标签扩展(用足够的空格替换每个标签,以填充到下一个显示列的 <n> 的倍数)。 --expand-tabs--expand-tabs=8 的简写,--no-expand-tabs--expand-tabs=0 的简写,它禁止标签扩展。

默认情况下,标签会以漂亮的格式展开,将日志信息缩进4个空格(即 "中",这是默认的,"全",和 "更全")。

--notes[=<引用>]

在显示提交日志信息时,显示注释提交的说明(见git-notes[1])。 这是`git log`、git show`和`git whatchanged`命令的默认设置,当命令行中没有给出--pretty`、--format`或--oneline`选项时。

默认情况下,显示的注释来自于`core.notesRef`和`notes.displayRef`变量(或相应的环境覆盖)中列出的注释参考。更多细节见git-config[1]

有了一个可选的 <引用> 参数,就可以使用引用来寻找要显示的笔记。 当引用以 refs/notes/ 开头时,可以指定完整的引用名称;当它以 notes/ 开头时, refs/ ,否则 refs/notes/ 前缀,形成引用的全名。

多个—​音符选项可以组合起来,控制哪些音符被显示。例如。"--notes=foo "将只显示来自 "refs/notes/foo "的注释;"--notes=foo --notes "将同时显示来自 "refs/notes/foo "和默认注释的注释。

--no-notes

不显示注释。这否定了上面的`--notes`选项,因为它重新设置了显示注释的注释列表。 选项按照命令行给出的顺序进行解析,因此,例如"--notes --notes=foo --no-notes --notes=bar "将只显示来自 "refs/notes/bar "的注释。

--show-notes-by-default

显示默认备注,除非给出了显示特定备注的选项。

--show-notes[=<引用>]
--[no-]standard-notes

这些选项已被废弃。请使用上面的 --notes/--no-notes 选项来代替。

--show-signature

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

--relative-date

`--date=relative`的同义词。

--date=<格式>

只对以人类可读格式显示的日期生效,例如使用`--pretty`时。log.date`配置变量为日志命令的--date`选项设置默认值。默认情况下,日期显示在原始时区(提交者或作者的时区)。如果`-local`被附加到格式中(例如,iso-local),就会使用用户的本地时区。

--date=relative`显示相对于当前时间的日期,例如:`2小时前''。--local`选项对`--date=relative`没有影响。

--date=local`是--date=default-local`的一个别名。

--date=iso(或 --date=iso8601 )以类似 ISO 8601 的格式显示时间戳。 与严格的 ISO 8601 格式的区别是:

  • 用空格代替`T`日期/时间分隔符

  • 时间和时区之间的空间

  • 时区的小时和分钟之间没有冒号

--date=iso-strict(或`--date=iso8601-strict`)显示严格的ISO 8601格式的时间戳。

--date=rfc(或`--date=rfc2822`)显示RFC 2822格式的时间戳,经常出现在电子邮件中。

--date=short`只显示日期,而不是时间,格式为`YYYY-MM-DD

--date=raw`显示日期为自纪元以来的秒数(1970-01-01 00:00:00 UTC),后面是空格,然后是时区为UTC的偏移量(一个+-的四位数字;前两位是小时,后两位是分钟)。也就是说,就像时间戳的格式为`strftime("%s %z"))。 请注意,`-local`选项不影响自始至终的秒数值(它总是以UTC为单位),但会切换伴随的时区值。

`--date=human`如果时区与当前时区不匹配,则显示时区,如果匹配则不打印整个日期(即对于 "今年 "的日期,跳过打印年份,但如果是最近几天的日期,也跳过整个日期本身,我们可以只说是哪个工作日)。 对于较早的日期,小时和分钟也被省略了。

--date=unix`显示日期为Unix纪元时间戳(自1970年以来的秒数)。 与--raw`一样,这总是以UTC为单位,因此`--local`没有影响。

--date=format:... 将格式 ... 输入到系统的 strftime 中,%z 和 %Z 除外,它们由内部处理。 使用 --date=format:%c,以系统语言首选的格式显示日期。 有关格式占位符的完整列表,请参阅 strftime 手册。使用 -local 时,正确的语法是 --date=format-local:...

--date=default`是默认格式,基于ctime(3)输出。 它仅仅在一行中显示缩写的星期、缩写的月份、一月中的第几天、"HH:MM:SS "格式的小时-分钟-秒,然后是年份,除非使用本地时区,在末尾都会加上时区信息,例如`Thu Jan 1 00:00:00 1970 +0000

--parents

也可以打印提交的父类(以 "提交父类…​ "的形式)。 也可以启用父级改写,见上面的 "历史简化"。

--children

同时打印提交的子项(以 "提交子项…​ "的形式)。 也可以启用父级改写,见上面的 "历史简化"。

--left-right

标明提交可以从对称性差异的哪一边到达。 左边的提交以 < 为前缀,右边的则以 > 为前缀。 如果与 --boundary 结合,这些提交的前缀为 -

例如,如果你有这样的拓扑结构:

	     y---b---b  branch B
	    / \ /
	   /   .
	  /   / \
	 o---x---a---a  branch A

你会得到这样的输出:

	$ git rev-list --left-right --boundary --pretty=oneline A...B

	>bbbbbbb... 3rd on b
	>bbbbbbb... 2nd on b
	<aaaaaaa... 3rd on a
	<aaaaaaa... 2nd on a
	-yyyyyyy... 1st on b
	-xxxxxxx... 1st on a
--graph

在输出的左手边绘制基于文本的提交历史图表。 这可能会导致在提交之间打印出额外的行,以便正确地绘制图形历史。 不能与`--no-walk`结合使用。

这可以使父代改写,见上面的’历史简化'。

这意味着默认情况下是`--topo-order`选项,但也可以指定`--date-order`选项。

--show-linear-break[=<阻隔>]

如果不使用 --graph,所有的历史分支都会被压扁,这就很难看出两个连续的提交并不属于一个线性分支。在这种情况下,该选项会在它们之间设置一个障碍。如果指定了"<barrier>",就会显示这个字符串,而不是默认的。

漂亮的格式

如果提交是一个合并,并且如果pretty-format不是 "oneline"、"email "或 "raw",那么在 "Author: "一行之前会插入一个附加行。 这一行的开头是 "Merge:这一行以 "Merge: "开头,并打印出祖先提交的哈希值,用空格分隔。 请注意,如果你限制了你的历史视图,那么列出的提交不一定是*直接*父级提交的列表:例如,如果你只对与某个目录或文件有关的修改感兴趣。

有几种内置的格式,你可以通过将 pretty.<名称> 配置选项设置为另一种格式名称或 format: 字符串来定义额外的格式,如下所述(见 git-config[1] )。下面是内置格式的细节:

  • oneline

    <哈希值> <标题行>

    这个设计是为了尽可能的紧凑。

  • short

    承诺<hash>
    作者。<作者>的情况
    <标题行>
  • medium

    commit <哈希值>
    Author: <作者>
    Date:   <提交日期>
    <标题行>
    <完整的提交信息
  • full

    承诺<hash>
    作者。< Author>
    承诺。<committer>(提交者)。
    <标题行>
    <完整的提交信息
  • fuller

    commit <哈希值>
    Author:     <作者>
    AuthorDate: <作者提交日期>
    Commit:     <提交者>
    CommitDate: <提交者提交日期>
    <标题行>
    <完整的提交信息
  • ‘引用’

    <缩写哈希值>(<标题行>,<简短的作者日期>)

    这种格式用于在提交信息中引用另一个提交,与`--pretty='format:%C(auto)%h (%s, %ad)'相同。 默认情况下,日期的格式为`--date=short`,除非明确指定其他`--date`选项。 与任何带有格式占位符的`format:一样,其输出不受其他选项的影响,如--decorate`和`--walk-reflogs`。

  • email

    From <哈希> <日期>
    From: <作者>
    Date: <作者提交日期>
    Subject: [PATCH] <标题行>
    <完整的提交信息
  • mboxrd

    和 "email "一样,但提交信息中以 "From "开头的行(前面有零个或多个">")用">"引出,这样就不会被混淆为开始了一个新的提交。

  • raw

    原始 "格式显示的是整个提交对象中存储的内容。 值得注意的是,无论是否使用了 --abbrev 或 --no-abbrev,哈希值都会被完整地显示出来,而’parent’信息会显示真正的父级提交,不会考虑移花接木或历史简化。注意,这种格式会影响提交的显示方式,但不会影响diff的显示方式,比如用`git log --raw`来显示。要获得原始差异格式的完整对象名称,请使用`--no-abbrev`。

  • format:<格式字符串>

    format:<格式字符串 格式允许你指定要显示的信息。它的工作原理有点像 printf 格式,但有一个明显的例外,那就是换行符是 %n 而不是 \n

    例如,format: "The author of %h was %an, %ar%nThe title was >>%s<<%n" 会显示这样的内容:

    fe6e0ee的作者是Junio C Hamano, 23小时前
    标题是 >>t4119: 测试传统diff输入的自动计算-p<n>。

    占位符是:

    • 占位符,可扩展为一个字面字符:

      %n

      换行

      %%

      一个原始的'%'

      %x00

      %x 后跟两个十六进制数字,会被一个包含十六进制数字值的字节替换(在本文档的其余部分,我们称之为 “字面格式化代码”)。

    • 影响后面占位符的格式化的占位符:

      %Cred

      切换颜色为红色

      %Cgreen

      切换颜色为绿色

      %Cblue

      将颜色改为蓝色

      %Creset

      重置颜色

      %C(…​)

      颜色规范,如git-config[1]的 "配置文件 "部分中的数值描述。 默认情况下,只有在启用日志输出时才会显示颜色(通过 color.diff, color.ui, 或 --color, 如果我们要去终端,要尊重前者的`auto`设置)。%C(auto,...)`被接受为默认的历史同义词(例如,%C(auto,red))。指定%C(always,…​)将显示颜色,即使没有启用颜色(尽管考虑使用--color=always`来启用整个输出的颜色,包括这个格式和其他任何git可能的颜色)。 auto`单独使用(即%C(auto)`)将在下一个占位符上开启自动着色,直到再次切换颜色。

      %m

      左(<)、右(>)或边界(-)标记

      %w([<w>[,<i1>[,<i2>]]])

      开关包行,就像 git-shortlog[1] 的 -w 选项。

      %<(<N>[,trunc|ltrunc|mtrunc])

      使下一个占位符至少占用 N 列宽,必要时在右侧填充空格。 如果输出超过 N 列,可选择在左侧(ltrunc)..ft、中间(mtrunc)mi..le 或末尾(trunc)rig.. 截断(用省略号 .. )。 注意 1:截断只在 N >= 2 时有效。 注 2:N 和 M(见下文)值周围的空格为可选项。 注 3:表情符号和其他宽字符将占用两个显示列,可能会超出列边界。 注 4:分解字符组合标记可能会在填充边界处错位。

      %<|(<M>)

      使下一个占位符至少显示到第 M 列,必要时在右侧填充空格。 从终端窗口右侧边缘测量的列位置使用负 M 值。

      %>(<N>), %>|(<M>)

      分别类似于 %<( <N> )%<|( <M> ),但在左侧填充空格

      %>>(<N>), %>>|(<M>)

      分别类似于'%>(<N>)%>|(<M>)',只是如果下一个占位符占用的空间比给定的多,并且其左侧有空格,则使用这些空格

      %><(<N>), %><|(<M>)

      分别类似于'%<( <N> )' 和 %<|( <M> ),但两边都有填充(即文本居中)

    • 占位符,扩展到从提交中提取的信息:

      %H

      提交的哈希值

      %h

      简称提交哈希

      %T

      目录树哈希值

      %t

      简称树形哈希

      %P

      父类哈希值

      %p

      缩写的父母哈希值

      %an

      作者名

      %aN

      作者名(关于 .mailmap,请参见 git-shortlog[1]git-blame[1]

      %ae

      作者电子邮箱

      %aE

      作者电子邮件(关于 .mailmap,请参见 git-shortlog[1]git-blame[1]

      %al

      作者电子邮件的本地部分(@ 符号之前的部分)

      %aL

      尊重 .mailmap 作者的本地部分(参见 %al ),参见 git-shortlog[1]git-blame[1])

      %ad

      作者日期(格式尊重—​date=选项

      %aD

      作者日期,RFC2822风格

      %ar

      作者日期,相对

      %at

      作者日期,UNIX时间戳

      %ai

      作者日期,类似ISO 8601的格式

      %aI

      作者日期,严格的ISO 8601格式

      %as

      作者日期,短格式( YYYY-MM-DD

      %ah

      作者日期,以易读形式呈现(就像 git-rev-list[1]--date=human 选项)

      %cn

      提交者名称

      %cN

      提交者名称(尊重 .mailmap,参见 git-shortlog[1]git-blame[1]

      %ce

      提交者电子邮箱

      %cE

      提交者电子邮箱(尊重 .mailmap,参见 git-shortlog[1]git-blame[1]

      %cl

      提交者电子邮件的本地部分(@ 符号之前的部分)

      %cL

      提交者本地部分(参见'%cl' )尊重 .mailmap, 参见 git-shortlog[1]git-blame[1])

      %cd

      承诺人日期(格式尊重—​date=选项

      %cD

      承诺人日期,RFC2822风格

      %cr

      承诺人日期,相对

      %ct

      提交者日期,UNIX时间戳

      %ci

      承诺人日期,类似ISO 8601的格式

      %cI

      承诺人日期,严格的ISO 8601格式

      %cs

      承诺人日期,短格式( YYYY-MM-DD

      %ch

      提交者的日期,人类风格(就像 git-rev-list[1]--date=human 选项)

      %d

      ref名称,就像git-log[1]的—​decorate选项。

      %D

      没有"("、")"包装的参考文献名称。

      %(decorate[:<选项>])

      自定义装饰的引用名称。decorate 字符串后面可以是冒号和零个或多个以逗号分隔的选项。选项值可能包含字面格式化代码。由于逗号(%x2C)和结尾括号(%x29)在选项语法中的作用,因此必须使用这些代码。

      • prefix=<值>: 显示在引用名称列表之前。 默认为 " ("。

      • suffix=<值>: 显示在引用名称列表之后。 默认为 ")"。

      • separator=<值>: 显示在引用名称之间。 默认为 ", "。

      • point=<值>: 显示在 HEAD 和其指向的分支(如果有)之间。 默认为 " -> "。

      • tag=<值>: 显示在标记名称之前。默认为 "tag: "。

    例如,制作不带包装或标签注释的装饰,并用空格作为分隔符:

    + %(decorate:prefix=,suffix=,tag=,separator= )

    %(describe[:<选项>])

    人类可读的名字,像git-describe[1];空字符串表示不可描述的提交。 `describe`字符串后面可以有冒号和零个或多个逗号分隔的选项。 当标签同时被添加或删除时,描述可能不一致。

    • tags[=<bool-value>]:不仅考虑带注释的标签,还考虑轻量级标签。

    • abbrev=<数量>:不使用缩写对象名称的默认十六进制位数(根据仓库中对象的数量而变化,默认为 7 位),而是使用 <数量> 的位数,或根据需要的位数来组成唯一的对象名称。

    • match=<pattern>:只考虑与给定的`glob(7)`模式匹配的标签,不包括 "refs/tags/"前缀。

    • exclude=<pattern>:不考虑匹配给定`glob(7)`模式的标签,排除 "refs/tags/"前缀。

    %S

    在命令行中给出的提交名称(如 git log --source),只对 git log 起作用

    %e

    编码方式

    %s

    主题

    %f

    经过消毒的主题行,适合于文件名

    %b

    正文

    %B

    原始体(未包装的主题和体)

    %N

    承诺说明

    %GG

    来自GPG的签名提交的原始验证信息

    %G?

    显示 "G" 代表一个好的(有效的)签名,"B" 代表一个坏的签名,"U" 代表一个有效性未知的好的签名,"X" 代表一个已经过期的好的签名,"Y" 代表一个由过期的钥匙制作的好的签名,"R" 代表一个由撤销的 钥匙制作的好的签名,"E" 如果不能检查签名(如缺少钥匙),"N" 代表没有签名

    %GS

    显示已签名的提交的签名者的名字

    %GK

    显示用于签署已签名的承诺的密钥

    %GF

    显示用于签署已签名提交文件的密钥的指纹

    %GP

    显示主键的指纹,该主键的子键被用来签署一个已签署的提交

    %GT

    显示用于签署已签名的承诺的密钥的信任级别

    %gD

    reflog选择器,例如,refs/stash@{1}`或`refs/stash@{2分钟前};其格式遵循`-g`选项的规则。@'前面的部分是命令行上给出的参考文献名称(所以`git log -g refs/heads/master`会产生`refs/heads/master@{0})。

    %gd

    简化的 reflog 选择器;与 %gD 相同,但 refname 部分被缩短以利于人类阅读(因此 refs/heads/master 变成了 master)。

    %gn

    记录身份名称

    %gN

    引用日志身份名称(尊重 .mailmap,参见 git-shortlog[1]git-blame[1]

    %ge

    重新记录身份邮件

    %gE

    引用日志身份电子邮箱(尊重 .mailmap,参见 git-shortlog[1]git-blame[1]

    %gs

    记录主题

    %(trailers[:<选项>])

    显示由 git-interpret-trailers[1] 解释的正文的为主。trailers 字符串后面可以有冒号和零个或多个逗号分隔的选项。 如果任何选项被多次提供,则最后出现的选项获胜。

    • key=<键>:只显示具有指定密钥的为主。匹配是不分大小写的,后面的冒号是可选的。如果多次给出选项,则显示与任何键匹配的为主行。该选项自动启用 only 选项,使拖车块中的非尾注行被隐藏。如果不希望这样,可以用 only=false 禁用。 例如,%(trailers:key=Reviewed-by) 显示键为 Reviewed-by 的拖车行。

    • only[=<布尔值>] :选择是否应该包括来自尾注块的非尾注行。

    • separator=<切片>:指定插入在尾注行之间的分隔符。如果不使用该选项,则每行以换行符结束。字符串 <切片> 可以包含上述字面格式化代码。要使用逗号作为分隔符,必须使用 %x2C,否则会被解析为下一个选项。例如,%(trailer:key=Ticket,separator=%x2C ) 显示所有关键字为 "Ticket" 的尾注行,并用逗号和空格分隔。

    • unfold[=<布尔值>]:使它的行为就像 interpret-trailer 的 --unfold 选项被给出一样。例如,`%(trailers:only,unfold=true)`会展开并显示所有的尾注行。

    • keyonly[=<布尔值>]:只显示尾注的关键部分。

    • valueonly[=<布尔值>]:只显示尾注的值部分。

    • key_value_separator=<切片>:指定在尾注行之间插入一个分隔符。当这个选项没有给出时,每个尾注的键值对都用 ": " 分开。 否则,它的语义与上面的 separator=<切片> 相同。

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

布尔选项接受一个可选的值`[=<布尔值>]。`true, false, on, `off`等值都可以接受。参见git-config[1]中 “示例” 的 “布尔” 子章节。如果一个布尔选项没有给出值,它就被启用。

如果你在占位符的'%后面加了一个`+(加号),当且仅当占位符扩展为一个非空字符串时,在扩展前会立即插入换行符。

如果你在占位符的'%后面加了一个`-(减号),如果且仅当占位符扩展为空字符串时,紧接着扩展前的所有连续换行将被删除。

如果你在占位符的'%'后面加了一个``(空格),当且仅当占位符扩展到一个非空字符串时,空格就会紧接着插入扩展。

  • t格式:

    tformat: 格式的工作原理与 format: 完全一样,只是它提供了 “终止符” 语义,而不是 “分隔符” 语义。换句话说,每个提交都附加了信息结束符(通常是换行符),而不是在条目之间放置一个分隔符。 这意味着单行格式的最后一个条目将正确地以新行结束,就像 “单行” 格式那样。 比如说:

    $ git log -2 --pretty=format:%h 4da45bef \
      | perl -pe '$_ .= " -- NO NEWLINE\n" unless /\n/'
    4da45be
    7134973 -- NO NEWLINE
    
    $ git log -2 --pretty=tformat:%h 4da45bef \
      | perl -pe '$_ .= " -- NO NEWLINE\n" unless /\n/'
    4da45be
    7134973

    此外,任何未被识别的字符串,如果其中有 % ,将被解释为前面有 tformat: 。 例如,这两个是等同的:

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

差异格式化

默认情况下,`git log`不会产生任何差异输出。下面的选项可以用来显示每次提交所做的修改。

请注意,除非明确给出了 --diff-merges 变体(包括短 -m-c--cc--dd 选项),否则合并提交不会显示差异,即使选择了 --patch 等差异格式,也不会匹配 -S 等搜索选项。使用 --first-parent 时例外,在这种情况下,--first-parent 是合并提交的默认格式。

-p
-u
--patch

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

-s
--no-patch

抑制差异(diff)工具的所有输出。 对于默认显示补丁的 git show 等命令,可以压制其输出,或在别名中取消命令行中的 --patch--stat 等选项的效果。

-m

以默认格式显示合并提交的差异。这与 --diff-merges=on 类似,但除非同时给出 -p,否则 -m 不会产生任何输出。

-c

生成合并提交的合并差异输出。 --diff-merges=combined -p 的快捷方式。

--cc

生成合并提交的密集合并差异输出。 --diff-merges=dense-combined -p 的快捷方式。

--dd

为合并提交和常规提交生成与第一父提交的差异。 --diff-merges=first-parent -p 的快捷方式。

--remerge-diff

生成合并提交的 remerge-diff 输出。 --diff-merges=remerge -p 的快捷方式。

--no-diff-merges

--diff-merges=off 的同义词。

--diff-merges=<格式>

指定合并提交时使用的差异格式。默认为 `off`,但当使用 --first-parent 选项时,默认为 first-parent

支持以下格式:

off, none

禁用合并提交时的差异输出。对覆盖隐含值很有用。

on, m

该选项使合并提交的差异输出以默认格式显示。-m 只有在 -p 的情况下才会产生输出。默认格式可以通过 log.diffMerges 配置参数改变,默认值为 separate

first-parent, 1

显示与第一个父提交的完整差异。这与 --patch 为非合并提交生成的格式相同。

separate

显示每个父代的完整差异。 每个父代都会生成单独的日志条目和差异。

combined, c

同时显示每个父文件与合并结果之间的差异,而不是逐个显示父文件与合并结果之间的成对差异。此外,它只列出从所有父文件修改过的文件。

dense-combined, cc

使用该选项,通过省略不感兴趣的块,进一步压缩 --diff-merges=combined 产生的输出,这类块在父提交中的内容只有两个变体,并且合并结果选择了其中一个而没有修改。 --cc 选项暗含 -p

remerge, r

重合双亲合并提交以创建临时目录树对象——可能包含冲突标记等文件。 然后会显示临时目录树与实际合并提交之间的差异。

使用该选项时发出的输出是可以改变的,它与其他选项的互动也是可以改变的(除非有明确的记录)。

--combined-all-paths

这个标志会使合并后的差异文件(用于合并提交)列出所有父提交的名称。,因此它只在使用 --diff-merges=[dense-]combined 时有效。其可能在检测到文件名变化时有用(例如,当要求检测重命名或复制时)。

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

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

--output=<文件>

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

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

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

--raw

对于每一个提交,使用原始的差异格式 请参见 git-diff[1] 中 “原始输出格式” 一节 。 这与显示日志中的本身的原始格式不同 你可以用 --format=raw 来实现。

--patch-with-raw

-p--raw 的同义词。

-t

在差异输出中显示目录树对象。

--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[=<宽度>[,<名称宽度>[,<数值>]]]

生成差异统计(diffstat)。默认情况下,文件名部分将使用尽可能多的空间,其余空间用于图表部分。最大宽度默认为终端宽度,如果未连接终端,则为 80 列,可以用 <最大宽度>`覆盖。文件名部分的宽度可以通过在逗号后另加宽度 `<文件名宽度>`或设置 `diff.statNameWidth=<文件名宽度>`来限制。图形部分的宽度可以通过使用 `--stat-graph-width=<图形宽度>`或设置 `diff.statGraphWidth=<图像宽度> 来限制。使用 --stat--stat-graph-width 选项会影响所有生成统计图的命令,而设置 diff.statNameWidthdiff.statGraphWidth 则不会影响 git format-patch。 通过给出第三个参数 <行数>,可以将输出限制在前 <行数>`行,如果行数更多,则在后面加上 `...

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

--compact-summary

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

--numstat

类似于 --stat,但是使用小数点和不含缩写的路径名显示添加和删除的行数,使其对程序更友好。对于二进制文件,输出两个 -,而不是 0 0

--shortstat

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

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

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

changes

通过计算从源文件中删除的行数或添加到目标文件中的行数来计算分布状态的数字。这忽略了文件内的代码移动行为。也就是说,在文件中重新排列的行不会像其他变化一样被计算在内。这是在没有给出参数时的默认行为。

lines

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

files

通过计算被改变的文件数量来计算分布状态的数字。在分布状态分析中,每一个被改变的文件都会被平等地计算。这是计算上开销最小的 --dirstat 行为,因为它无需查看文件内容。

cumulative

子目录中的变化计算到父目录中。 注意,当使用 cumulative 选项时,报告的百分比之和可能超过 100%。默认的(非累积)行为可以用 noncumulative 参数指定。

<limit>

一个整数参数,其指定一个截止百分比(默认为 3%)。贡献值小于这个百分比的目录不显示在输出中。

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

--cumulative

--dirstat=cumulative 同义

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

与 --dirstat=files,<参数 1>,<参数 2> 同义

--summary

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

--patch-with-stat

同义词 -p --stat

-z

用 NUL 而不是用换行来分隔提交。

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

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

--name-only

只显示更改过的文件的名称。文件名通常以 UTF-8 编码。 更多信息见 git-log[1] 手册页中关于编码的讨论。

--name-status

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

--submodule[=<格式>]

指定子模块中的差异如何显示。当指定 --submodule=short 选项时,会使用 short 格式。这种格式只显示范围的开头和结尾处的提交名称。当指定了 --submodule--submodule=log 时,会使用 log 格式。这种格式会像 git-submodule[1] summary 那样,列出该范围内的提交。当指定了 --submodule=diff 时,会使用 diff 格式。这个格式显示的是子模块内在提交范围之间的变化差异。默认为 diff.submodule,如果配置选项未设置, 则为 short 格式。

--color[=<when>]

显示有颜色的差异。--color(即不含 =<何时>)与 --color=always 相同。<何时> 可以是 alwaysneverauto

--no-color

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

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

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

no

被移动的行不突出显示。

default

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

plain

任何在某个位置被添加,且在另一个位置被删除的行,都会被用 color.diff.newMoved 着色。同样的,在差异中在某处删除且在其它地方添加的行会使用 color.diff.oldMoved 着色。这种模式可以读取任何被移动的行,但在代码审查中,它不能确定一个代码块是否未经排列而进行了移动。

blocks

使用贪心方法检测含至少 20 个字母数字字符的移动文本块。检测到的区块使用 color.diff.{old,new}Moved 的颜色。相邻的区块不能被区分开。

zebra

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

dimmed-zebra

类似于 zebra 模式,但对使移动的代码中不关注的部分变暗。相邻两个区块的边界线被认为是重要,其余的部分是无关紧要的。dimmed_zebra 是一个被废弃的同义词。

--no-color-moved

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

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

这将配置在执行 --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[=<模式>]

显示词的差异,用 <模式> 来分隔已更改的词。默认情况下,单词是以空格分隔;请参考 --word-diff-regex。<模式> 默认为 plain,并且必须是以下其中之一:

color

只用颜色突出显示已更改的单词。暗含 --color 选项。

plain

显示更改的词为 [-removed-]{+added+}。如果在输入中出现定界符,则不尝试转义,所以输出可能是多义的。

porcelain

使用一种特殊的、基于行的格式,供脚本使用。添加/删除/未更改的运行数据以通常的统一的差异格式输出,行的开头以 + / - / ` ` 字符开始,一直到行的结尾。输入中的新行用单行上的 `~`表示。

none

再次禁用单词差异模式。

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

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

使用 <正则表达式> 来确定单词的格式,而不是将一串非空白行视为单词。除非已启用,否则还暗含 --word-diff 选项。

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

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

正则表达式也可以通过差异程序或配置选项来设置,参见 gitattributes[5]git-config[1]。显式指明会覆盖任何程序或配置。差异程序会覆盖配置。

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

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

--no-renames

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

--[no-]rename-empty

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

--check

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

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

突出显示差异中 context(上下文)、old(旧)或 new(新)行中的空格错误。多个值用逗号隔开,none 选项会重置以前的值,default 重置列表为 newallold,new,context 的简写。当没有给定这个选项,并且配置变量 diff.wsErrorHighlight 没有设置时,只有 new 行中的空格错误会被高亮显示。空格错误会用 color.diff.whitespace 配置进行着色。

--full-index

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

--binary

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

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

它会影响决定更改形式的阈值,当单个文件内修改总量达到一定值时,会认为该文件进行了完全重写,而不是将一系列删除和插入操作视为修改。如果视为多个删除和插入修改,修改中的行可能会碰巧在文本上与原文一致,从而被当作上下文。选项中的数字 m 控制 -B 选项的这一方面(默认为 60%)。-B/70% 表示,如果在结果中保留的原始内容少于原始内容的30%,则 Git 认为它是完全重写的(否则,生成的补丁将是一系列删除和插入,并与上下文行混合在一起)。

使用 -M 选项时,一个完全改写的文件也被认为是重命名文件的来源(通常 -M 只考查一个消失文件作为重命名的来源)。选项中的数量 n 控制 -B 选项的这一方面(默认为 50%)。-B20% 表明,当插入与删除比 20% 的文件大小更多,该文件可作为重命名到另一文件的可能来源。

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

如果制成差异,检测并报告每个提交中的重命名。 对于每个在遍历历史时重命名的文件,参见 --follow。 如果指定了 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<数量>

-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 排除添加和删除的路径。

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

-S<string>

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

当您正在寻找确切的代码块(如结构体),并且想知道该块自首次出现以来的历史记录时,这将非常有用:通过 -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<顺序控制文件>

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

输出顺序由 <顺序控制文件> 中的 glob 模式的顺序决定。所有路径名与第一个模式匹配的文件首先输出,路径名与第二个模式匹配(但不与第一个模式匹配)的文件其次输出,以此类推。所有路径名与任何模式匹配的文件会最后输出,就像在文件末尾有一个隐含的全部匹配模式。如果多个路径名具有相同的等级(它们匹配相同的模式,但没有匹配先前的模式),它们相对于彼此的输出顺序是正常的。

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

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

  • 以井号("#")开头的行会被忽略,所以它们可以用来做注释。如果模式以井号开头,则需要在模式的开头加上反斜杠("\")。

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

模式的语法和语义与 fnmatch(3) 中使用的相同,不包括 FNM_PATHNAME 标志,但在删除路径名中结尾任意几个成分后匹配的情况下例外。例如,模式 "foo*bar" 匹配 "fooasdfbar" 和 "foo/bar/baz/asdf",但不匹配 "foobarx"。

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

从输出中丢弃命名 <文件> 之前的文件(即 skip to),或将它们移到输出的末尾(即 rotate to)。 这些选项主要是为使用 git difftool 命令而发明的,在其他情况下可能用处不大。

-R

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

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

当从项目的子目录中运行时,可以排除目录外的变化,并通过这个选项显示相对于它的路径名。当你不在子目录中时(例如在纯仓库中),你可以通过 <路径> 参数来指明要使输出相对于哪个子目录。--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<正则表达式>
--ignore-matching-lines=<正则表达式>

忽略所有行均匹配 <正则表达式> 的更改。 此选项可指定多次。

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

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

-W
--function-context

在每个修改中的上下文行显示整个函数。函数名称的确定方式与 git diff 计算补丁头的方式相同(参见 gitattributes[5] 中的 自定义区块头 )。

--ext-diff

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

--no-ext-diff

禁止使用外部差异器。

--textconv
--no-textconv

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

--ignore-submodules[=<when>]

在生成差异时忽略子模块的修改。<when> 可以是 "none"、"untracked"、"dirty " 或 "all","all" 是默认选项。使用 "none" 会在子模块包含未跟踪或修改的文件,或者它的HEAD 与上级项目中记录的提交不同时,认为它被修改了,并且可以用来覆盖 git-config[1]gitmodules[5]忽略 选项的设置。当使用 "untracked" 时,当子模块只包含未跟踪的内容时,它们不会被认为是有改动的(但它们仍然会被扫描是否有被修改的内容)。使用 "dirty" 会忽略所有对子模块工作树的修改,只有存储在上级项目中的提交的修改才会被显示出来(这是在1.7.0之前的行为)。使用 "all" 会隐藏所有对子模块的修改。

--src-prefix=<前缀>

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

--dst-prefix=<前缀>

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

--no-prefix

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

--default-prefix

使用默认的源和目标前缀("a/"和 "b/")。 这通常已经是默认的,但可以用来覆盖配置,如 diff.noprefix

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

使用选项 -p 生成补丁文本

使用 -p 选项运行 git-diff[1]、linkgit:git-log[1]、linkgit:git-show[1]、linkgit:git-diff-index[1]、linkgit:git-diff-tree[1]git-diff-files[1] 会生成补丁文本。 你可以通过 GIT_EXTERNAL_DIFFGIT_DIFF_OPTS 环境变量(参见 git[1]),以及 diff 属性(参见 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 <模式>,<模式>

    mode<模式>,<模式>..<模式> 行仅在 <模式> 中至少有一个与其余的不同时才会出现。包含有关检测到的内容移动的信息 (重命名和复制检测) 的扩展标头设计为使用两个 <目录树对象> 的 diff,不能用于组合的 diff 格式。

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

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

    与传统 ‘统一’ 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> @@@

    块中有(父提交数量+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,又称 "他们的版本")。

实例

git log --no-merges

显示整个提交历史,但跳过任何合并内容

git log v2.6.12.. include/scsi drivers/scsi

显示自版本 v2.6.12 以来改变 include/scsidrivers/scsi 子目录中任何文件的所有提交

git log --since="2 weeks ago" -- gitk

显示过去两周内对文件 gitk 的修改。 -- 是必要的,以避免与名为 gitk分支 相混淆

git log --name-status release..test

显示在 "test "分支中但尚未在 "release "分支中的提交,以及每个提交修改的路径列表。

git log --follow builtin/rev-list.c

显示改变`builtin/rev-list.c`的提交,包括那些在文件被赋予现在名字之前发生的提交。

git log --branches --not --remotes=origin

显示所有在本地分支中但不在 "origin "的远程跟踪分支中的提交(你有而origin没有的东西)。

git log master --not --remotes=*/master

显示所有在本地主库但不在任何远程仓库主库分支中的提交。

git log -p -m --first-parent

显示包括变化差异的历史,但只从 "主分支 "的角度,跳过来自合并分支的提交,并显示合并带来的全部变化差异。 这只有在遵循严格的政策,在停留在一个集成分支时合并所有主题分支时才有意义。

git log -L '/int main/',/^}/:main.c

显示了文件`main.c`中的函数`main()`是如何随时间演变的。

git log -3

将显示的提交数量限制在3个。

讨论

Git在某种程度上是与字符编码无关的。

  • blob对象的内容是未经解释的字节序列。 在核心层没有编码转换。

  • 路径名以UTF-8规范化形式C编码,这适用于树对象、索引文件、参考名称,以及命令行参数、环境变量和配置文件(.git/config(见git-config[1]),linkgit:gitignore[5],linkgit:gitattributes[5]gitmodules[5])中的路径名。

    请注意,Git 在核心层将路径名简单地视为非 NUL 字节的序列,没有路径名编码的转换(除了 Mac 和 Windows)。因此,即使在使用传统的扩展ASCII编码的平台和文件系统上,使用非ASCII的路径名大多也能工作。然而,在这种系统上创建的仓库在基于UTF-8的系统(如Linux、Mac、Windows)上将无法正常工作,反之亦然。 此外,许多基于Git的工具简单地认为路径名称是UTF-8,而不能正确显示其他编码。

  • 提交日志信息通常以UTF-8编码,但也支持其他扩展ASCII编码。这包括ISO-8859-x、CP125x和其他许多编码,但不包括UTF-16/32、EBCDIC和CJK多字节编码(GBK、Shift-JIS、Big5、EUC-x、CP9xx等)。

尽管我们鼓励提交日志信息使用UTF-8编码,但核心系统和Git Porcelain的设计并不强制要求项目使用UTF-8。 如果某个项目的所有参与者都认为使用传统编码更方便,Git也不会禁止。 然而,有几件事需要注意。

  1. git commitgit commit-tree 如果收到的提交日志信息不像是有效的 UTF-8 字符串,就会发出警告,除非你明确表示你的项目使用的是传统编码。 说这个的方法是在 .git/config 文件中设置 i18n.commitEncoding,像这样:

    [i18n]
    	commitEncoding = ISO-8859-1

    用上述设置创建的提交对象在它的 encoding 头中记录了 i18n.commitEncoding 的值。 这是为了帮助以后看这些对象的人。 缺少这个头意味着提交日志信息是以 UTF-8 编码的。

  2. git loggit showgit blame 和它们的朋友们会查看提交对象的 encoding 头,并尝试将日志信息重新编码为 UTF-8,除非另有指定。 您可以在`.git/config` 文件中使用 i18n.logOutputEncoding 指定所需的输出编码,像这样:

    [i18n]
    	logOutputEncoding = ISO-8859-1

    如果你没有这个配置变量,则使用`i18n.commitEncoding`的值来代替。

请注意,我们特意选择在提交对象层面上,不对提交日志信息进行重新编码,因为重新编码为UTF-8不一定是一个可逆的操作。

配置

核心变量见 git-config[1] ,与 diff 生成相关的设置见 git-diff[1]

format.pretty

`--format`选项的默认值。 (见上面的 "漂亮的格式"。)默认为 "中等"。

i18n.logOutputEncoding

显示日志时要使用的编码。 (见上面的 "讨论"。)如果设置了,默认为`i18n.commitEncoding`的值,否则为UTF-8。

Warning

Missing zh_HANS-CN/includes/cmd-config-section-rest.txt

See original version for this content.

Warning

Missing zh_HANS-CN/config/log.txt

See original version for this content.

Warning

Missing zh_HANS-CN/config/notes.txt

See original version for this content.

GIT

属于 git[1] 文档

scroll-to-top