简体中文 ▾ 主题 ▾ 最新版本 ▾ git-rev-list 上次更新于 2.55.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)之前应用的。

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

限制仅输出将要显示的前 <数字> 个提交。

--max-count-oldest=<数字>

限制仅输出将要显示的最后 <数字> 个提交。

--skip=<数字>

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

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

显示比 <日期> 更近的提交。作为一个特殊情况,today 表示刚刚过去的午夜。

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

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

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

显示比 <date> 旧的提交。

--max-age=<时间戳>
--min-age=<时间戳>

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

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

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

--grep-reflog=<模式>

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

--grep=<模式>

将提交输出限制为其日志消息匹配 <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=<数字>
--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

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

--exclude-first-parent-only

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

--maximal-only

将输出的提交限制为那些在修订范围内无法从任何其他提交到达的提交。

--not

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

--all

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

--branches[=<模式>]

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

--tags[=<模式>]

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

--remotes[=<模式>]

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

--glob=<通配符模式>

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

--exclude=<通配符模式>

不包括与下一个 --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

不在标准输出中打印任何内容。此形式主要用于允许调用者测试退出状态,以确定一组对象是否完全连接(或不完全连接)。这比将标准输出重定向到 /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

尝试使用包位图索引(如果可用)来加速遍历。请注意,在使用 --objects 遍历时,树(tree)和数据对象(blob)将不会打印与其关联的路径。

--progress=<标头>

在处理对象时,在标准错误(stderr)中显示进度报告。每次更新进度时,都会打印 <标头> 文本。

-z

每个输出的对象及其伴随的元数据不再以换行符分隔,而是使用空字节(NUL)分隔。输出以下列形式打印

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

附加的对象元数据(例如对象路径或边界对象)使用 <标记>=<值> 形式打印。标记值按原样打印,不进行任何编码/截断。对象 ID(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> 的提交。

--simplify-by-decoration

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

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

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

默认 模式

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

--show-pulls

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

--full-history

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

--dense

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

--sparse

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

--simplify-merges

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

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

当给定一个要显示的提交范围(例如 <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> 本身的提交。

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

	    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 进行 eval 的文本。这些行将把中点版本的名称赋值给变量 bisect_rev,将测试 bisect_rev 后预期要测试的提交数量赋值给 bisect_nr,将如果 bisect_rev 测试结果为好(good)时预期要测试的提交数量赋值给 bisect_good,将如果 bisect_rev 测试结果为坏(bad)时预期要测试的提交数量赋值给 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

按提交顺序打印树(tree)和数据对象(blob)的 ID。树和数据对象的 ID 会在它们被提交首次引用后打印。

--objects-edge

类似于 --objects,但还会打印排除的提交的 ID,并带有前缀“-”字符。这被 git-pack-objects[1] 用于构建“瘦”包(thin pack),该包基于这些排除的提交中包含的对象,以差异化(deltified)形式记录对象,从而减少网络流量。

--objects-edge-aggressive

类似于 --objects-edge,但它会以增加时间为代价更努力地寻找排除的提交。这用于代替 --objects-edge 来为浅克隆(shallow)仓库构建“瘦”包。

--indexed-objects

假装索引使用的所有树(tree)和数据对象(blob)都列在了命令行上。请注意,你可能还需要使用 --objects

--unpacked

仅对 --objects 有用;打印不在包(pack)中的对象 ID。

--object-names

仅对 --objects 有用;打印找到的对象 ID 的名称。这是默认行为。请注意,每个对象的“名称”是模糊的,主要用作打包对象时的提示。特别是:不区分标签、树和数据对象的名称;可能会修改路径名以去除换行符;如果一个对象以不同的名称出现多次,则仅显示一个名称。

--no-object-names

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

--filter=<过滤器规范>

仅与 --objects* 之一结合使用时有用;在打印的对象列表中省略某些对象(通常是数据对象)。<过滤器规范> 可以是以下之一

格式 --filter=blob:none 省略所有数据对象。

格式 --filter=blob:limit=<n>[kmg] 省略大小至少为 <n> 字节或指定单位的数据对象。<n> 可以为零。后缀 kmg 可用于分别指定 KiB、MiB 或 GiB 单位。例如, blob:limit=1kblob:limit=1024 相同。

格式 --filter=object:type=(tag|commit|tree|blob) 将省略所有非请求类型的对象。请注意,除非同时指定了 --filter-provided-objects,否则显式提供的对象会忽略过滤器并始终被打印。

格式 --filter=sparse:oid=<类似数据对象> 使用数据对象(或数据对象表达式)<类似数据对象> 中包含的稀疏检出(sparse-checkout)规范,来省略在请求的引用上进行稀疏检出时不需要的数据对象。

格式 --filter=tree:<深度> 省略与根树的深度大于等于 <深度> 的所有数据对象和树(如果在遍历的提交中一个对象位于多个深度,则取最小深度)。<深度>=0 将不包括任何树或数据对象,除非在命令行中显式包含(或在使用 --stdin 时的标准输入中包含)。<深度>=1 将仅包含由可从 <提交> 或显式给出的对象直接引用的树和数据对象。<深度>=2 与 <深度>=1 类似,同时还包括距离显式给出的提交或树更深一层的树和数据对象。

请注意,出于安全原因,已废弃了试图从文件系统上任意路径读取的 --filter=sparse:path=<路径> 格式。

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

格式 --filter=combine:<过滤器1>+<过滤器2>+...<过滤器N> 也可用于组合多个过滤器,但这比直接重复使用 --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=error 要求在遇到缺失对象时 rev-list 报错停止。这是默认动作。

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

格式 --missing=allow-promisor 类似于 allow-any,但仅在遇到“预期的”(EXPECTED)承诺方(promisor)缺失对象时才允许对象遍历继续。遇到非预期的缺失对象将会报错。

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

格式 --missing=print-info 类似于 print,但还会打印推断自其包含对象的、关于缺失对象的附加信息。所有信息都与缺失的对象 ID 打印在同一行,格式为:?<oid> [<标记>=<值>]...。包含附加信息的 <标记>=<值> 键值对相互之间以空格(SP)分隔。值是以特定于该标记的方式编码的,但值中所包含的 SP(空格)或 LF(换行)总是会以某种方式表示,以使得最终编码后的值不包含这两个可能有问题的内容。每个 <标记>=<值> 可以是以下之一

  • path=<路径> 显示推断自包含对象的缺失对象的路径。如果路径包含空格(SP)或特殊字符,则会根据需要在两侧加上 C 语言风格的双引号。

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

如果传递给遍历的某些顶端引用(tips)丢失了,它们也将被视为缺失,遍历将忽略它们。然而,如果我们无法获取它们的对象 ID,则会触发错误。

--exclude-promisor-objects

(仅供内部使用。)在承诺方边界处预过滤对象遍历。这与部分克隆结合使用。这比 --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> 可以是 `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 头中记录了日志消息使用的字符编码;此选项可用于告诉命令将提交日志消息重新编码为用户首选的编码。对于非底层命令,默认为 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=<格式>

仅在以人类可读格式显示日期时生效(例如,使用 `--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

以原始格式(raw-format)打印提交的内容;每条记录用空字符(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[=<分界符>]

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

--graph-lane-limit=<n>

使用 --graph 时,限制显示的图形通道数量。超出限制的通道将替换为截断标记 ~。默认情况下,它设置为 0(无限制),零值和负值将被忽略并视为无限制。

--count

打印一个数字,表示将列出多少个提交,并抑制所有其他输出。当与 --left-right 一起使用时,则打印左侧和右侧提交的数量,用制表符(tab)分隔。当与 --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:<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(<规范>)

    颜色规范,如 git-config[1] “配置文件”部分的“值”中所述。默认情况下,仅在为日志输出启用颜色时(通过 color.diffcolor.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)截断(使用省略号 ..),在中间(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

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

    %(count)

    补丁序列中补丁的编号。仅在 format-patch--commit-list-format 中使用。

    %(total)

    补丁序列中补丁的总数。仅在 format-patch--commit-list-format 中使用。

    %(decorate[:<选项>,...])

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

    prefix=<值>

    在引用名称列表之前显示。默认为 " ("。

    suffix=<值>

    在引用名称列表之后显示。默认为 ")"。

    separator=<值>

    在引用名称之间显示。默认为 ", "。

    pointer=<值>

    显示在 HEAD 和它指向的分支之间(如果有的话)。默认为 " → "。

    tag=<值>

    在标签名称之前显示。默认为 "tag: "。

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

        %(decorate:prefix=,suffix=,tag=,separator= )
    %(describe[:<选项>,...])

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

    tags[=<布尔值>]

    不仅考虑带注释的标签,也考虑轻量级标签。

    abbrev=<数字>

    使用 <number> 位十六进制数字(或者形成唯一对象名所需的位数)来代替默认的缩写对象名称位数(默认通常为 7,具体取决于仓库中的对象数量)。

    match=<模式>

    仅考虑匹配给定的 glob(7) <pattern> 的标签,不包含 refs/tags/ 前缀。

    exclude=<模式>

    不考虑匹配给定的 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[:<选项>,...])

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

    key=<键>

    仅显示具有指定 <key> 的结尾行。匹配时不区分大小写,且结尾冒号是可选的。如果多次指定该选项,则会显示匹配任意键的结尾行。此选项会自动启用 only 选项,以便隐藏结尾块中的非结尾行。如果不需要此行为,可以使用 only=false 禁用它。例如,%(trailers:key=Reviewed-by) 显示键为 Reviewed-by 的结尾行。

    only[=<布尔值>]

    选择是否应包含结尾块中的非结尾行。

    separator=<分隔符>

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

    unfold[=<布尔值>]

    使其表现得就像给出了 interpret-trailer 的 --unfold 选项一样。例如,%(trailers:only,unfold=true) 会展开并显示所有结尾行。

    keyonly[=<布尔值>]

    仅显示结尾的键部分。

    valueonly[=<布尔值>]

    仅显示结尾的值部分。

    key_value_separator=<分隔符>

    指定插入到每个结尾行的键和值之间的分隔符。默认为 ": "。否则,它具有与上面的 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
  • 打印当前分支上存在但上游(upstream)分支上不存在的提交列表。

    git rev-list @{upstream}..HEAD
  • 格式化提交,显示其作者和提交信息(另请参阅高级命令 git-log[1])。

    git rev-list --format=medium HEAD
  • 格式化提交并伴随其差异(diff)(另请参阅上层命令 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
  • 打印从当前分支可达的对象列表(即,所有提交以及它们包含的数据对象和树)。

    git rev-list --objects HEAD
  • 比较所有可达对象、可从引用日志(reflogs)可达的对象以及打包总大小的磁盘大小。这可以告诉你运行 git repack -ad 是否可以减小仓库大小(通过丢弃不可达对象),以及清理过期引用日志是否有帮助。

    # 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] 套件的一部分