简体中文 ▾ 主题 ▾ 最新版本 ▾ git-rev-list 最后更新于 2.52.0

名称

git-rev-list - 按时间倒序列出提交对象

概要

git rev-list [<options>] <commit>…​ [--] [<path>…​]

描述

列出通过给定提交(们)的 parent 链接可达的提交,但排除前面带 ^ 的提交(们)可达的提交。默认输出按时间倒序。

你可以将此理解为集合运算。命令行中给出的提交(们)可达的提交构成一个集合,然后从该集合中减去前面带 ^ 的提交(们)可达的提交。剩余的提交就是命令的输出。各种其他选项和路径参数可用于进一步限制结果。

因此,以下命令

$ git rev-list foo bar ^baz

表示“列出所有可达自 foobar,但不可达自 baz 的提交”。

特殊的表示法 "<commit1>..<commit2>" 可用作 "^<commit1> <commit2>" 的简写。例如,以下任一写法都可互换使用

$ git rev-list origin..HEAD
$ git rev-list HEAD ^origin

另一个特殊的表示法是 "<commit1>...<commit2>",这对合并很有用。由此产生的提交集是两个操作数之间的对称差集。以下两个命令是等效的

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

rev-list 是一个至关重要的 Git 命令,因为它提供了构建和遍历提交祖系图的能力。因此,它拥有许多不同的选项,使其能够被 git bisectgit repack 等不同命令使用。

选项

提交限制

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

使用更多选项通常会进一步限制输出(例如,--since=<date1> 限制为比 <date1> 更新的提交,并且将其与 --grep=<pattern> 一起使用会进一步限制为其日志消息中有一行与 <pattern> 匹配的提交),除非另有说明。

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

-<number>
-n <number>
--max-count=<number>

将输出限制为 <number> 个提交。

--skip=<number>

在开始显示提交输出之前,跳过 <number> 个提交。

--since=<date>
--after=<date>

显示比 <date> 更新的提交。

--since-as-filter=<date>

显示所有比 <date> 更新的提交。这会遍历范围内的所有提交,而不是在第一个比 <date> 旧的提交处停止。

--until=<date>
--before=<date>

显示比 <date> 旧的提交。

--max-age=<timestamp>
--min-age=<timestamp>

将提交输出限制在指定的时间范围内。

--author=<pattern>
--committer=<pattern>

将提交输出限制为作者/提交者标题行与 <pattern> 正则表达式匹配的提交。使用多个 --author=<pattern> 时,会选择作者匹配任何 <pattern> 的提交(对多个 --committer=<pattern> 类似)。

--grep-reflog=<pattern>

将提交输出限制为 reflog 条目与 <pattern> 正则表达式匹配的提交。使用多个 --grep-reflog 时,会选择 reflog 消息匹配任何给定模式的提交。使用此选项但未同时使用 --walk-reflogs 是错误的。

--grep=<pattern>

将提交输出限制为其日志消息匹配 <pattern> 正则表达式的提交。使用多个 --grep=<pattern> 时,会选择消息匹配任何 <pattern> 的提交(但请参阅 --all-match)。

--all-match

限制提交输出为匹配所有给定 --grep 的提交,而不是匹配至少一个的提交。

--invert-grep

将提交输出限制为其日志消息不匹配使用 --grep=<pattern> 指定的 <pattern> 的提交。

-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=<number>
--max-parents=<number>
--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

在查找要包含的提交时,遇到合并提交时仅跟随第一个父提交。此选项在查看特定主题分支的演变时可能提供更好的概览,因为合并到主题分支通常只是为了调整上游的更新,并且此选项允许您忽略此类合并带来的历史中的单个提交。

--exclude-first-parent-only

在查找要排除的提交(使用 ^)时,遇到合并提交时仅跟随第一个父提交。当给定任意合并可以是有效主题分支更改时,这可用于查找主题分支从其与远程分支分叉的点开始的更改集。

--not

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

--all

假装 refs/ 中的所有引用以及 HEAD 都已在命令行上列为 <commit>

--branches[=<pattern>]

假装 refs/heads 中的所有引用都已在命令行上列为 <commit>。如果给出了 <pattern>,则将分支限制为与给定 shell glob 匹配的分支。如果 <pattern> 缺少 ?*[,则在末尾隐含 /*

--tags[=<pattern>]

假装 refs/tags 中的所有引用都已在命令行上列为 <commit>。如果给出了 <pattern>,则将标签限制为与给定 shell glob 匹配的标签。如果模式缺少 ?*[,则在末尾隐含 /*

--remotes[=<pattern>]

假装 refs/remotes 中的所有引用都已在命令行上列为 <commit>。如果给出了 <pattern>,则将远程跟踪分支限制为与给定 shell glob 匹配的分支。如果模式缺少 ?*[,则在末尾隐含 /*

--glob=<glob-pattern>

假装所有匹配 shell glob <glob-pattern> 的引用都已在命令行上列为 <commit>。如果缺少,则自动加上前缀 refs/。如果模式缺少 ?*[,则在末尾隐含 /*

--exclude=<glob-pattern>

不包括与下一个 --all--branches--tags--remotes--glob 将要考虑的 <glob-pattern> 匹配的引用。此选项的重复使用会累积排除模式,直到下一个 --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

假装由 reflog 提及的所有对象都已在命令行上列为 <commit>

--alternate-refs

假装备用存储库的引用尖端中提到的所有对象都已在命令行上列出。备用存储库是其对象目录在 objects/info/alternates 中指定的任何存储库。包含的对象集可能由 core.alternateRefsCommand 等修改。请参阅 git-config[1]

--single-worktree

默认情况下,当存在多个工作树时(请参阅 git-worktree[1]),以下选项将检查所有工作树:--all--reflog--indexed-objects。此选项强制它们仅检查当前工作树。

--ignore-missing

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

--stdin

除了从命令行获取参数外,还可以从标准输入读取它们。这接受提交和伪选项,如 --all--glob=。当看到 -- 分隔符时,后面的输入被视为路径并用于限制结果。通过 stdin 读取的标志(如 --not)仅对以相同方式传递的参数有效,并且不会影响任何后续命令行参数。

--quiet

不要向标准输出打印任何内容。此形式主要用于允许调用者测试退出状态,以查看对象范围是否完全连接(或不)。它比将 stdout 重定向到 /dev/null 快,因为不需要格式化输出。

--disk-usage
--disk-usage=human

抑制正常输出;而是打印所选提交或对象在磁盘上存储所使用的字节总数。这等同于将输出通过管道传递给 git cat-file --batch-check='%(objectsize:disk),但运行速度快得多(特别是与 --use-bitmap-index 结合使用时)。请参阅 git-cat-file[1] 中的 CAVEATS 部分,了解“磁盘存储”的局限性。使用可选值 human 时,磁盘存储大小会以人类可读的字符串显示(例如 12.24 Kib, 3.50 Mib)。

--cherry-mark

类似于 --cherry-pick(见下文),但用 = 标记等效提交而不是省略它们,用 + 标记不等效提交。

--cherry-pick

当提交集合通过对称差异限制时,省略与“另一侧”的另一个提交引入相同更改的任何提交。

例如,如果您有两个分支 AB,列出它们其中一个分支上所有提交的常用方法是使用 --left-right(请参阅下面的 --left-right 选项的说明中的示例)。但是,它会显示从另一个分支 cherry-pick 的提交(例如,“b 上的第 3 个”可能从分支 A cherry-pick)。使用此选项,将从输出中排除此类提交对。

--left-only
--right-only

仅列出对称差集一侧的提交,即仅那些由 --left-right 标记为 <> 的提交。

例如,--cherry-pick --right-only A...B 将 B 中在 A 中或与 A 中的提交补丁等效的提交从 B 中省略。换句话说,这列出了 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 除外,原因显而易见),这会导致输出包含来自 reflog 的两行额外信息。输出中的 reflog 标识符可能显示为 ref@{<Nth>}(其中 <Nth> 是 reflog 中按时间倒序的索引)或 ref@{<timestamp>}(带有该条目的 <timestamp>),具体取决于一些规则。

  1. 如果起始点指定为 ref@{<Nth>},则显示索引格式。

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

  3. 如果两者都未用,但命令行上给出了 --date,则以 --date 请求的格式显示时间戳。

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

--pretty=oneline 下,提交消息在该行上以这些信息为前缀。此选项不能与 --reverse 结合使用。另请参阅 git-reflog[1]

--pretty=reference 模式下,此信息将完全不显示。

--merge

显示在 HEAD...<other> 范围内接触已冲突路径的提交,其中 <other>MERGE_HEADCHERRY_PICK_HEADREVERT_HEADREBASE_HEAD 中的第一个存在的伪引用。仅当索引包含未合并条目时才有效。此选项可用于在解决 3 路合并冲突时显示相关提交。

--boundary

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

--use-bitmap-index

尝试使用 pack bitmap 索引(如果可用)来加速遍历。请注意,在使用 --objects 进行遍历时,树和 blob 的关联路径将不会被打印。

--progress=<header>

在考虑对象时,在 stderr 上显示进度报告。 <header> 文本将随每次进度更新一起打印。

-z

输出的每个对象及其附带的元数据将使用 NUL 字节分隔,而不是换行符分隔。输出形式如下

<OID> NUL [<token>=<value> NUL]...

附加的对象元数据,例如对象路径或边界对象,使用 <token>=<value> 形式打印。Token 值按原样打印,不进行任何编码/截断。OID 条目永远不包含 = 字符,因此用于信号标记新对象记录的开始。示例

<OID> NUL
<OID> NUL path=<path> NUL
<OID> NUL boundary=yes NUL
<OID> NUL missing=yes NUL [<token>=<value> NUL]...

此模式仅与 --objects, --boundary, 和 --missing 输出选项兼容。

历史简化

有时您只对历史的一部分感兴趣,例如修改特定 <path> 的提交。但是,"历史简化" 有两个部分,一部分是选择提交,另一部分是如何选择,因为存在各种简化历史的策略。

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

<paths>

选择修改给定 <paths> 的提交。

--simplify-by-decoration

选择被某些分支或标签引用的提交。

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

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

默认 模式

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

--show-pulls

包含默认模式中的所有提交,但也包括任何与第一个父提交不 TREESAME 但与较晚的父提交 TREESAME 的合并提交。此模式有助于显示“首次引入”更改到分支的合并提交。

--full-history

与默认模式相同,但不会修剪某些历史。

--dense

只显示选定的提交,以及一些具有有意义历史的提交。

--sparse

显示简化历史中的所有提交。

--simplify-merges

--full-history 的附加选项,用于从结果历史中删除一些不必要的合并,因为没有选定的提交对此合并有所贡献。

--ancestry-path[=<commit>]

当给定一个要显示的提交范围(例如 <commit1>..<commit2><commit2> ^<commit1>),以及该范围内的提交 <commit> 时,只显示在该范围内是 <commit> 的祖先、<commit> 的后代,或者 <commit> 本身的提交。如果没有指定提交,则将 <commit1>(范围中排除的部分)用作 <commit>。可以多次传递;如果是这样,如果一个提交是给定的任何提交之一,或者它是其中一个的祖先或后代,则包含该提交。

更详细的解释如下。

假设您指定了 foo 作为 <paths>。我们将调用修改 foo 的提交为 !TREESAME,其余的为 TREESAME。(在为 foo 过滤的 diff 中,它们分别看起来不同和相同。)

在下文中,我们将始终引用相同的历史示例来阐述简化设置之间的差异。我们假设您正在此提交图中过滤文件 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)。

  • Dfoo 设置为 baz。其合并 OND 的字符串合并为 foobarbaz;即,它与任何父项都不同(!TREESAME)。

  • Equux 更改为 xyzzy,其合并 P 将字符串合并为 quux xyzzyPO 是 TREESAME,但与 E 不是。

  • X 是一个独立的根提交,它添加了一个新文件 side,而 Y 修改了它。YX 是 TREESAME。其合并 Qside 添加到 P,而 QP 是 TREESAME,但与 Y 不是。

rev-list 向后遍历历史记录,根据是否使用了 --full-history 和/或父项重写(通过 --parents--children)来包含或排除提交。以下是可用的设置。

默认模式

包含的提交是那些与任何父项都不同的提交(尽管这可以改变,请参见下文的 --sparse)。如果提交是合并,并且它与一个父项是 TREESAME,则只跟随该父项。(即使有多个 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。 ECB 都被遍历,但只有 B 是 !TREESAME,因此其他的不出现。

请注意,如果没有父级重写,很难真正谈论提交之间的父/子关系,因此我们将它们显示为断开连接。

--full-history 带父提交重写

普通提交仅在它们是 !TREESAME 时才包含(尽管这可以更改,请参阅下面的 --sparse)。

合并总是被包含。然而,它们的父列表被重写:沿每个父列表,修剪掉本身未包含的提交。这导致

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

与上面的“不进行父项重写的 --full-history”进行比较。请注意,E 被删除了,因为它本身是 TREESAME,但 P 的父项列表被重写为包含 E 的父项 I。对于 CN,以及 XYQ,也发生了同样的情况。

除了上述设置之外,您还可以更改 TREESAME 是否影响包含

--dense

被遍历的提交如果与任何父级都不是 TREESAME,则会被包含。

--sparse

所有被遍历的提交都将被包含。

请注意,没有 --full-history,这仍然会简化合并:如果其中一个父级是 TREESAME,我们只跟踪那一个,因此合并的其他侧永远不会被遍历。

--simplify-merges

首先,以与 --full-history 带父级重写相同的方式构建历史图(见上文)。

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

  • C' 设置为 C

  • C' 的每个父项 P 替换为其简化后的 P'。在此过程中,删除是其他父项的祖先或与空树 TREESAME 的根提交的父项,并删除重复项,但注意永远不要删除所有我们是 TREESAME 的父项。

  • 如果在此父重写之后,C' 是一个根提交或合并提交(具有零或 >1 个父级),一个边界提交,或 !TREESAME,则它保持不变。否则,它将被其唯一父级替换。

通过与带父重写的 --full-history 进行比较,最能体现其效果。示例变为

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

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

  • N 的父项列表中删除了 I,因为它是另一个父项 M 的祖先。但是,N 仍然被保留,因为它与任何父项都不同(!TREESAME)。

  • P 的父列表类似地移除了 IP 随后被完全移除,因为它有一个父级且是 TREESAME。

  • Q 的父项列表将 Y 简化为 XX 然后被删除,因为它是一个 TREESAME 的根提交。Q 然后被完全删除,因为它只有一个父项并且是 TREESAME。

还有另一种简化模式可用

--ancestry-path[=<commit>]

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

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

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

常规的 D..M 计算 M 的祖先的提交集,但排除 D 的祖先的提交。这对于查看自 D 以来 M 的历史记录中发生了什么非常有用,从“M 拥有 D 中不存在的什么”的意义上来说。在此示例中的结果将是所有提交,除了 A 和 B(以及 D 本身,当然)。

然而,当我们想找出 M 中的哪些提交受到了 D 引入的 bug 的污染并需要修复时,我们可能只想查看 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
		 \
	      C---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,该文件被 ABX 以不同的方式修改。单父提交 CZY 不更改 file.txt。合并提交 M 是通过解决合并冲突而创建的,以包含 AB 的所有更改,因此它与其中任何一个都不同(非 TREESAME)。然而,合并提交 R 是通过忽略 M 处的 file.txt 内容而创建的,只采用了 X 处的 file.txt 内容。因此,RX 是 TREESAME 的,但与 M 不是。最后,创建 N 的自然合并解析是采用 R 处的 file.txt 内容,因此 NR 是 TREESAME 的,但与 C 不是。合并提交 OP 与它们的第一个父提交是 TREESAME 的,但与它们的第二个父提交 ZY 分别不是。

在使用默认模式时,NR 都具有一个 TREESAME 父级,因此那些边缘被遍历,而其他的则被忽略。生成的历史图是

	I---X

使用 `--full-history` 时,Git 会遍历每个边。这将发现提交 A 和 B 以及合并 M,但也会显示合并提交 O 和 P。使用父项重写后,生成的图是:

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

在这里,合并提交 O 和 P 贡献了额外的噪音,因为它们实际上没有为 `file.txt` 贡献更改。它们只是合并了一个基于旧版本 `file.txt` 的主题。这是在许多贡献者并行工作并将主题分支合并到单条主线的工作流中常见的存储库问题:许多不相关的合并出现在 `--full-history` 的结果中。

当使用 `--simplify-merges` 选项时,提交 O 和 P 将从结果中消失。这是因为 O 和 P 的重写后的第二个父项可以从它们的第一个父项到达。这些边被移除,然后这些提交看起来像单父提交,并且与它们的父项是 TREESAME。提交 N 也发生这种情况,导致历史视图如下:

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

在此视图中,我们看到了 A、B 和 X 的所有重要的单父提交更改。我们还看到了仔细解析的合并 M 和不太仔细解析的合并 R。这通常足以确定为什么提交 A 和 B 在默认视图中“消失”了。但是,此方法存在一些问题。

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

第二个问题是审计。当许多贡献者在同一个存储库中工作时,哪个合并提交将更改引入重要分支是很重要的。上面的有问题的合并 R 很可能不是用于将 R 合并到重要分支的合并提交。相反,合并 N 用于将 R 和 X 合并到重要分支。该提交可能包含有关 X 的更改覆盖 A 和 B 的更改原因的信息。

--show-pulls

除了默认历史中显示的提交外,显示每个与其第一个父级不是 TREESAME 但与其后续父级是 TREESAME 的合并提交。

当合并提交被 `--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(可能被简化掉)。

二分法辅助

--bisect

将输出限制为包含提交和排除提交之间大致中间的那个提交对象。请注意,错误的二分法引用 refs/bisect/bad 被添加到包含提交中(如果存在),而正确的二分法引用 refs/bisect/good-* 被添加到排除提交中(如果存在)。因此,假设 refs/bisect/ 中没有引用,如果

	$ git rev-list --bisect foo ^bar ^baz

输出 midpoint,则两个命令的输出

	$ git rev-list foo ^midpoint
	$ git rev-list midpoint ^bar ^baz

将大致相同长度。因此,找到引入回归的更改被简化为二分查找:反复生成和测试新的“midpoint”,直到提交链长度为一。

--bisect-vars

这计算的结果与 --bisect 相同,除了 refs/bisect/ 中的引用不被使用,并且它输出文本,准备被 shell 求值。这些行将中间修订版的名称赋给变量 bisect_rev,在测试 bisect_rev 后预期的要测试的提交数量赋给 bisect_nr,如果 bisect_rev 被证明是正确的,预期的要测试的提交数量赋给 bisect_good,如果 bisect_rev 被证明是错误的,预期的要测试的提交数量赋给 bisect_bad,以及我们目前正在进行二分法的提交数量赋给 bisect_all

--bisect-all

这输出包含提交和排除提交之间的所有提交对象,并按它们与包含和排除提交的距离排序。 refs/bisect/ 中的引用不被使用。最远的那个首先显示。(这是 --bisect 显示的唯一一个。)

这很有用,因为它使得在你想因为某些原因(例如可能无法编译)而避免测试某些提交时,很容易选择一个好的提交进行测试。

此选项可以与 --bisect-vars 一起使用,在这种情况下,在所有排序的提交对象之后,将有与单独使用 --bisect-vars 时相同的文本。

提交排序

默认情况下,提交按逆时间顺序显示。

--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 仓库的打包。

--objects

打印列出的提交引用的任何对象的对象 ID。--objects foo ^bar 因此表示“如果我有提交对象 bar 但没有 foo,请发送给我所有我需要下载的对象 ID”。另见下文的 --object-names

--in-commit-order

按提交顺序打印树和 blob ID。树和 blob ID 在首次被提交引用后打印。

--objects-edge

类似于 --objects,但也打印排除提交的 ID,前面加上 "-" 字符。这由 git-pack-objects[1] 使用来构建“瘦” pack,它以增量形式记录对象,基于这些排除提交中的对象,以减少网络流量。

--objects-edge-aggressive

类似于 --objects-edge,但它会更努力地寻找排除的提交,但代价是增加时间。这被用于代替 --objects-edge 来构建浅仓库的“瘦” pack。

--indexed-objects

假装索引使用的所有树和 blob 都列在命令行上。请注意,您可能也想使用 --objects

--unpacked

仅与 --objects 有效;打印不在 pack 中的对象 ID。

--object-names

仅与 --objects 有效;打印找到的对象 ID 的名称。这是默认行为。请注意,每个对象的“名称”是模糊的,并且主要用于打包对象。特别是:标签、树和 blob 的名称之间没有区分;路径名可能被修改以删除换行符;如果一个对象出现多次但名称不同,则只显示一个名称。

--no-object-names

仅与 --objects 有效;不打印找到的对象 ID 的名称。这与 --object-names 相反。此标志允许 git cat-file [1] 等命令更容易地解析输出。

--filter=<filter-spec>

仅与 --objects* 之一有效;从打印的对象列表中省略对象(通常是 blob)。<filter-spec> 可以是以下之一

--filter=blob:none 形式省略所有 blob。

--filter=blob:limit=<n>[kmg] 形式省略大小至少为 <n> 字节或单位的 blob。<n> 可以为零。后缀 kmg 可用于命名 KiB、MiB 或 GiB 为单位。例如,blob:limit=1k 等同于 blob:limit=1024

--filter=object:type=(tag|commit|tree|blob) 形式省略所有非请求类型的对象。

--filter=sparse:oid=<blob-ish> 形式使用 blob(或 blob 表达式)<blob-ish> 中包含的稀疏检出规范,来省略在请求的引用上进行稀疏检出时不需要的 blob。

--filter=tree:<depth> 形式省略深度从根树开始大于等于 <depth> 的所有 blob 和树(如果对象位于遍历的提交中的多个深度,则为最小深度)。<depth>=0 不包含任何树或 blob,除非它们被显式包含在命令行中(或在 --stdin 使用时从标准输入读取)。<depth>=1 只包含由可达自 <commit> 或显式指定的对象引用的树和 blob。<depth>=2 类似于 <depth>=1,同时还包含与显式指定的提交或树相隔一个级别的树和 blob。

请注意,为安全起见,已删除了 --filter=sparse:path=<path> 这种从文件系统任意路径读取的表单。

可以指定多个 --filter= 标志来组合过滤器。只有被每个过滤器接受的对象才会被包含。

还可以使用 --filter=combine:<filter1>+<filter2>+...<filterN> 形式组合多个过滤器,但这比简单地重复 --filter 标志要麻烦,通常是不必要的。过滤器由 + 连接,单个过滤器经过 % 编码(即 URL 编码)。除了 +% 字符外,以下字符也是保留字符,也必须进行编码:~!@#$^&*()[]{}\;",<>?'` 以及所有 ASCII 码小于等于 0x20 的字符,包括空格和换行符。

也可以对其他任意字符进行编码。例如,combine:tree:3+blob:nonecombine:tree%3A3+blob%3Anone 是等效的。

--no-filter

关闭任何先前指定的 --filter= 参数。

--filter-provided-objects

过滤显式提供的对象列表,这些对象否则将始终被打印,即使它们不匹配任何过滤器。仅与 --filter= 一起使用。

--filter-print-omitted

仅与 --filter= 一起使用;打印由过滤器省略的对象列表。对象 ID 前面带有 "~" 字符。

--missing=<missing-action>

一个调试选项,用于帮助未来的“部分克隆”开发。此选项指定如何处理缺失的对象。

--missing=error 形式要求 rev-list 在遇到缺失对象时停止并报错。这是默认操作。

--missing=allow-any 形式允许在遇到缺失对象时继续进行对象遍历。缺失的对象将静默地从结果中省略。

--missing=allow-promisor 形式类似于 allow-any,但仅允许预期中的 promisor 缺失对象继续遍历。意外的缺失对象将引发错误。

--missing=print 形式类似于 allow-any,但还会打印缺失对象的列表。对象 ID 前面带有 "?" 字符。

--missing=print-info 形式类似于 print,但还会打印关于从其包含对象推断出的缺失对象的附加信息。信息全部打印在同一行,缺失对象 ID 的形式为:?<oid> [<token>=<value>]...。包含附加信息的 <token>=<value> 对之间由一个空格分隔。值以 token 特定方式进行编码,但值中包含的 SPLF 始终被期望以不会包含这两个问题字节的形式进行编码。每个 <token>=<value> 可能为以下之一

  • path=<path> 显示从包含对象推断出的缺失对象的路径。包含 SP 或特殊字符的路径将根据需要以 C 风格的双引号括起来。

  • type=<type> 显示从包含对象推断出的缺失对象的类型。

如果传递给遍历的某些提示缺失,它们也将被视为缺失,并且遍历将忽略它们。如果我们无法获得它们的 Object ID,将引发错误。

--exclude-promisor-objects

(仅供内部使用。)在 promisor 边界处预过滤对象遍历。这与部分克隆一起使用。这比 --missing=allow-promisor 更强大,因为它限制了遍历,而不是仅仅屏蔽缺失对象的错误。

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

只显示给定的提交,但不遍历它们的祖先。如果没有指定范围,则此选项无效。如果给定了参数 `unsorted`,则按命令行给出的顺序显示提交。否则(如果给定了 `sorted` 或没有参数),则按提交时间的倒序显示提交。不能与 `--graph` 结合使用。

--do-walk

覆盖之前的 --no-walk 选项。

提交格式化

使用这些选项,git-rev-list[1] 将类似于更专业的提交日志工具系列:git-log[1]git-show[1]git-whatchanged[1]

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

以给定的格式漂亮地打印提交日志的内容,其中 <format> 可以是 `oneline`、`short`、`medium`、`full`、`fuller`、`reference`、`email`、`raw`、`format:<string>` 和 `tformat:<string>`。当 <format> 不是上述任何一种,并且包含 %<placeholder> 时,它就像给定了 `--pretty=tformat:<format>` 一样。

有关每种格式的更多详细信息,请参阅“PRETTY FORMATS”部分。当省略 =<format> 部分时,默认为 `medium`。

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

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

这应该能让使用 80 列终端的人更容易阅读 `--pretty=oneline`。

--no-abbrev-commit

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

--oneline

这是 `--pretty=oneline --abbrev-commit` 的简写。

--encoding=<encoding>

提交对象在它们的 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 个空格(即 `medium`,这是默认值,`full` 和 `fuller`)。

--show-signature

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

--relative-date

等同于 --date=relative

--date=<format>

仅在以人类可读格式显示日期时生效(例如,使用 `--pretty` 时)。`log.date` 配置变量为 `git log` 命令的 `--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:<format>` 将 <format> 传递给系统的 `strftime`,但 `%s`、`%z` 和 `%Z` 除外,它们由内部处理。使用 `--date=format:%c` 以系统区域设置的首选格式显示日期。有关格式占位符的完整列表,请参阅 `strftime`(3) 手册。使用 `-local` 时,正确的语法是 `--date=format-local:<format>`。

`--date=default` 是默认格式,基于 ctime(3) 输出。它显示一行,包含三字母星期几、三字母月份、日期、小时-分钟-秒(格式为“HH:MM:SS”)、四位数字年份,以及时区信息,除非使用本地时区,例如 `Thu Jan 1 00:00:00 1970 +0000`。

--header

以原始格式打印提交内容;每个记录都以 NUL 字符分隔。

--no-commit-header

抑制包含 "commit" 和指定格式之前打印的对象 ID 的标题行。这对内置格式没有影响;只影响自定义格式。

--commit-header

覆盖先前的 --no-commit-header

--parents

同时打印提交的父提交(格式为 "commit parent…​")。也启用父提交重写,参见上文的 历史简化

--children

同时打印提交的子提交(格式为 "commit child…​")。也启用父提交重写,参见上文的 历史简化

--timestamp

打印原始提交时间戳。

--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[=<barrier>]

当不使用 `--graph` 时,所有历史分支都会被展平,这可能难以看出两个连续的提交不属于线性分支。在这种情况下,此选项会在它们之间放置一个分隔符。如果指定了 <barrier>,则它将是显示而不是默认字符串。

--count

打印将要列出的提交数量,并禁止所有其他输出。当与 --left-right 一起使用时,则打印左右提交的数量,并用制表符分隔。当与 --cherry-mark 一起使用时,则从这些计数中省略补丁等价提交,并用制表符分隔等价提交的数量。

美观格式 (PRETTY FORMATS)

如果该提交是合并提交,并且美化格式不是 `oneline`、`email` 或 `raw`,则在 `Author:` 行之前会插入一个额外的行。该行以“Merge: ”开头,并打印祖先提交的哈希值,用空格分隔。请注意,如果已限制历史记录视图(例如,如果您只关心与某个目录或文件相关的更改),则列出的提交不一定就是 *直接* 父提交的列表。

有几种内置格式,您可以通过将 pretty.<name> 配置选项设置为另一个格式名称或 format: 字符串来定义其他格式,如下所述(请参阅 git-config[1])。以下是内置格式的详细信息。

  • oneline

    <hash> <title-line>

    这被设计为尽可能紧凑。

  • short

    commit <hash>
    Author: <author>
    <title-line>
  • medium

    commit <hash>
    Author: <author>
    Date:   <author-date>
    <title-line>
    <full-commit-message>
  • full

    commit <hash>
    Author: <author>
    Commit: <committer>
    <title-line>
    <full-commit-message>
  • fuller

    commit <hash>
    Author:     <author>
    AuthorDate: <author-date>
    Commit:     <committer>
    CommitDate: <committer-date>
    <title-line>
    <full-commit-message>
  • reference

    <abbrev-hash> (<title-line>, <short-author-date>)

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

  • email

    From <hash> <date>
    From: <author>
    Date: <author-date>
    Subject: [PATCH] <title-line>
    <full-commit-message>
  • mboxrd

    与 email 类似,但提交消息中以 "From " 开头的行(前面可以有零个或多个 ">")会被 ">" 引用,这样它们就不会被误认为是开始了一个新提交。

  • raw

    raw 格式显示存储在提交对象中的完整提交。特别是,无论是否使用了 --abbrev 或 --no-abbrev,都会显示完整的哈希值,并且 *parents* 信息显示真实的父提交,而不考虑 graft 或历史简化。请注意,此格式会影响提交的显示方式,但不会影响 diff 的显示方式,例如使用 git log --raw。要在原始 diff 格式中获取完整的对象名称,请使用 --no-abbrev。

  • format:<format-string>

    format:<format-string> 格式允许您指定要显示的信息。它的工作方式有点像 printf 格式,但有一个明显的区别是,您需要使用 %n 而不是 \n 来获得一个换行符。

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

    The author of fe6e0ee was Junio C Hamano, 23 hours ago
    The title was >>t4119: test autocomputing -p<n> for traditional diff input.<<

    占位符有

    • 扩展为单个文字字符的占位符

      %n

      换行

      %%

      一个字面意义上的 '%'

      %x00

      %x 后跟两位十六进制数字将被替换为具有该十六进制数字值的字节(在本文档的其余部分,我们将此称为“字面格式化代码”)。

    • 影响后续占位符格式的占位符

      %Cred

      切换颜色为红色

      %Cgreen

      切换颜色为绿色

      %Cblue

      切换颜色为蓝色

      %Creset

      重置颜色

      %C(<spec>)

      颜色规范,如 git-config[1] 的 "CONFIGURATION FILE" 部分的 Values 中所述。默认情况下,颜色仅在为日志输出启用时显示(通过 color.diffcolor.ui--color,并尊重前者的 auto 设置(如果我们正在输出到终端))。%C(auto,<spec>) 被接受为默认值的历史同义词(例如,%C(auto,red))。指定 %C(always,<spec>) 将即使颜色未被其他方式启用时也显示颜色(但可以考虑仅使用 --color=always 来为整个输出启用颜色,包括此格式和 git 可能着色的任何其他内容)。单独使用 auto(即 %C(auto))将在下一个占位符处自动开启颜色,直到颜色再次被切换。

      %m

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

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

      切换换行,类似于 git-shortlog[1] 的 -w 选项。

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

      使下一个占位符至少占用 N 列宽度,如果需要,则在右侧填充空格。如果输出超过 N 列,则可以选择在左侧(ltrunc)截断(使用省略号 ..),在中间(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

      作者的本地部分(请参阅 %al),遵循 .mailmap,请参阅 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

      引用名称,类似于 git-log[1] 的 --decorate 选项

      %D

      引用名称,不带 " ("、")" 包裹。

      %(decorate[:<option>,...])

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

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

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

      • separator=<value>:显示在 ref 名称之间。默认为 ", "。

      • pointer=<value>:显示在 HEAD 和它指向的分支之间(如果有)。默认为 " → "。

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

    例如,生成不带包裹或标签注释的装饰,并使用空格作为分隔符

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

    %(describe[:<option>,...])

    人类可读的名称,类似于 git-describe[1];对于无法描述的提交,则为空字符串。describe 字符串后面可以跟一个冒号和零个或多个逗号分隔的选项。当同时添加或删除标签时,描述可能会不一致。

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

    • abbrev=<number>:而不是使用默认的十六进制数字数量(这将根据存储库中的对象数量而变化,默认为 7),使用 <number> 位数字,或者根据需要使用的数字以形成唯一的对象名称。

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

    • exclude=<pattern>:不考虑匹配给定 glob(7) <pattern> 的标签,不包括 refs/tags/ 前缀。

    %S

    在命令行上给出的引用名称,通过它到达了提交(如 git log --source),仅适用于 git log

    %e

    编码

    %s

    主题

    %f

    净化后的主题行,适合作为文件名

    %b

    正文

    %B

    原始正文(未回绕的主题和正文)

    %GG

    来自 GPG 的原始验证消息,用于已签名提交

    %G?

    显示 "G" 表示良好(有效)签名,"B" 表示不良签名,"U" 表示有效性未知但签名为良好,"X" 表示已过期的良好签名,"Y" 表示由已过期密钥生成的良好签名,"R" 表示由已撤销密钥生成的良好签名,"E" 表示签名无法验证(例如,缺少密钥)和 "N" 表示无签名。

    %GS

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

    %GK

    显示用于签署已签名提交的密钥

    %GF

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

    %GP

    显示其子密钥用于签署已签名提交的主密钥指纹

    %GT

    显示用于签署已签名提交的密钥的信任级别

    %gD

    reflog 选择器,例如,refs/stash@{1} 或 refs/stash@{2 minutes ago};格式遵循 -g 选项所述的规则。@ 符号之前的部分是命令行中给出的 refname(因此 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[:<option>,...])

    显示由 git-interpret-trailers[1] 解释的提交正文的尾部。trailers 字符串后面可以跟一个冒号和零个或多个逗号分隔的选项。如果任何选项出现多次,则最后一个生效。

    • key=<key>:只显示具有指定 <key> 的尾部。匹配不区分大小写,并且尾部冒号是可选的。如果多次给出此选项,则显示匹配任何键的尾部行。此选项会自动启用 `only` 选项,因此尾部块中的非尾部行将被隐藏。如果不需要,可以使用 `only=false` 禁用它。例如,%(trailers:key=Reviewed-by) 显示键为 `Reviewed-by` 的尾部行。

    • only[=<bool>]:选择是否包含尾部块中的非尾部行。

    • separator=<sep>:指定在尾部行之间插入的分隔符。默认为换行符。字符串 <sep> 可以包含上面描述的字面格式化代码。要使用逗号作为分隔符,必须使用 %x2C,因为它否则会被解析为下一个选项。例如,%(trailers:key=Ticket,separator=%x2C ) 显示所有键为 "Ticket" 的尾部行,以逗号和空格分隔。

    • unfold[=<bool>]:使其表现得好像给定了 interpret-trailer 的 --unfold 选项。例如,%(trailers:only,unfold=true) 会展开并显示所有尾部行。

    • keyonly[=<bool>]:只显示尾部的键部分。

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

    • key_value_separator=<sep>:指定在每个尾部的键和值之间插入的分隔符。默认为 ": "。否则,它与上面的 separator=<sep> 具有相同的语义。

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

布尔选项接受一个可选值 [=<bool-value>]。--type=bool git-config[1] 中的值,如 yes 和 off,都被接受。给出布尔选项而不带 =<value> 等同于给出 =true。

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

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

如果在占位符的 % 后面加上空格,当且仅当占位符扩展为非空字符串时,会在其扩展之前立即插入一个空格。

  • tformat

    tformat: 格式与 format: 完全相同,不同之处在于它提供“终止符”语义而不是“分隔符”语义。换句话说,每个提交都会附加消息终止符(通常是换行符),而不是在条目之间放置分隔符。这意味着单行格式的最后一个条目将正确地以换行符终止,就像 "oneline" 格式一样。例如

    $ 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 rev-list HEAD
  • 打印此分支上的提交列表,但排除上游分支上的提交。

    git rev-list @{upstream}..HEAD
  • 按作者和提交消息格式化提交(另请参阅 git-log[1] 的 porcelain 格式)。

    git rev-list --format=medium HEAD
  • 格式化提交及其差异(另请参阅 git-log[1],它可以在单个进程中完成此操作)。

    git rev-list HEAD |
    git diff-tree --stdin --format=medium -p
  • 打印当前分支上修改了 Documentation 目录中任何文件的提交列表。

    git rev-list HEAD -- Documentation/
  • 打印过去一年中由您在本机上编写的所有分支、标签或其他引用上的提交列表。

    git rev-list --author=you@example.com --since=1.year.ago --all
  • 打印当前分支可达的对象列表(即,它们包含的所有提交、blob 和 tree)。

    git rev-list --objects HEAD
  • 比较可达对象总数与 reflog 可达对象数以及已打包对象总数的磁盘大小。这可以告诉您运行 git repack -ad 是否可以减少仓库大小(通过丢弃不可达对象),以及是否可以延长 reflog 生命周期。

    # reachable objects
    git rev-list --disk-usage --objects --all
    # plus reflogs
    git rev-list --disk-usage --objects --all --reflog
    # total disk size used
    du -c .git/objects/pack/*.pack .git/objects/??/*
    # alternative to du: add up "size" and "size-pack" fields
    git count-objects -v
  • 报告每个分支的磁盘大小,不包括当前分支使用的对象。这可以找到导致仓库膨胀的异常值(例如,因为有人意外提交了大型构建工件)。

    git for-each-ref --format='%(refname)' |
    while read branch
    do
    	size=$(git rev-list --disk-usage --objects HEAD..$branch)
    	echo "$size $branch"
    done |
    sort -n
  • 比较一组引用中的分支在磁盘上的大小,排除另一组。如果您在单个仓库中混合了来自多个远程仓库的对象,这可以显示哪些远程仓库对仓库大小有贡献(以 origin 的大小为基线)。

    git rev-list --disk-usage --objects --remotes=$suspect --not --remotes=origin

GIT

Git[1] 套件的一部分