English ▾ 主题 ▾ 最新版本 ▾ git-shortlog 最后更新于 2.49.0

名称

git-shortlog - 总结 git log 输出

概要

git shortlog [<options>] [<revision-range>] [[--] <path>…​]
git log --pretty=short | git shortlog [<options>]

描述

以适合包含在发布公告中的格式总结 git log 输出。每个提交将按作者和标题分组。

此外,"[PATCH]" 将从提交描述中删除。

如果在命令行上没有传递任何修订版本,并且标准输入不是终端或者没有当前分支,则 git shortlog 将输出从标准输入读取的日志的摘要,而不参考当前存储库。

选项

-n
--numbered

根据每个作者的提交数量而不是作者字母顺序对输出进行排序。

-s
--summary

抑制提交描述,仅提供提交计数摘要。

-e
--email

显示每个作者的电子邮件地址。

--format[=<format>]

不要使用提交主题,而是使用其他一些信息来描述每个提交。<format> 可以是 git log--format 选项接受的任何字符串,例如 * [%h] %s。(参见 git-log[1] 的“PRETTY FORMATS”部分。)

Each pretty-printed commit will be rewrapped before it is shown.
--date=<format>

显示按照给定日期字符串格式化的日期。(参见 git-log[1] 的“Commit Formatting”部分中的 --date 选项)。与 --group=format:<format> 一起使用很有用。

--group=<type>

基于 <type> 对提交进行分组。如果未指定 --group 选项,则默认为 author<type> 是其中之一

  • author,提交按作者分组

  • committer,提交按提交者分组(与 -c 相同)

  • trailer:<field><field> 被解释为不区分大小写的提交消息预告片(参见 git-interpret-trailers[1])。例如,如果你的项目使用 Reviewed-by 预告片,你可能想使用 git shortlog -ns --group=trailer:reviewed-by 来查看谁在进行审查。

  • format:<format>git log--format 选项接受的任何字符串。(参见 git-log[1] 的“PRETTY FORMATS”部分。)

    请注意,不包含预告片的提交将不被计数。同样,具有多个预告片的提交(例如,多个签名)可能会被多次计数(但每个提交中每个唯一的预告片值只计数一次)。

    Shortlog 将尝试将每个预告片值解析为 name <email> 标识。如果成功,则应用邮件映射,除非指定了 --email 选项,否则将省略电子邮件。如果该值无法解析为标识,它将被按字面意义完全采用。

如果多次指定 --group,则将在每个值下对提交进行计数(但同样,每个提交中每个唯一值只计数一次)。例如,git shortlog --group=author --group=trailer:co-authored-by 同时计数作者和共同作者。

-c
--committer

这是 --group=committer 的别名。

-w[<width>[,<indent1>[,<indent2>]]]

通过在 width 处包装每行来对输出进行换行。每个条目的第一行缩进 indent1 个空格,第二行和后续行缩进 indent2 个空格。widthindent1indent2 默认为 76、6 和 9。

如果 width 为 0(零),则缩进输出的行而不进行换行。

<revision-range>

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

[--] <path>…​

仅考虑足以解释与指定路径匹配的文件是如何形成的提交。

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

提交限制

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

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

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

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

限制要输出的提交数量。

--skip=<number>

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

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

显示比指定日期更新的提交。

--since-as-filter=<date>

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

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

显示比指定日期旧的提交。

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

将提交输出限制为具有与指定模式(正则表达式)匹配的作者/提交者标题行的提交。对于多个 --author=<pattern>,选择作者与任何给定模式匹配的提交(对于多个 --committer=<pattern> 也是如此)。

--grep-reflog=<pattern>

将提交输出限制为具有与指定模式(正则表达式)匹配的 reflog 条目的提交。对于多个 --grep-reflog,选择其 reflog 消息与任何给定模式匹配的提交。除非正在使用 --walk-reflogs,否则使用此选项是错误的。

--grep=<pattern>

将提交输出限制为具有与指定模式(正则表达式)匹配的日志消息的提交。对于多个 --grep=<pattern>,选择其消息与任何给定模式匹配的提交(但请参见 --all-match)。

--notes 生效时,来自注释的消息将被匹配,就像它是日志消息的一部分一样。

--all-match

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

--invert-grep

将提交输出限制为具有与使用 --grep=<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 提供所有 octopus 合并。

--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 匹配的分支。如果模式缺少 ?*[,则暗示末尾的 /*

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

假装作为备用存储库的 ref 提示提及的所有对象都列在命令行上。备用存储库是指其对象目录在 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(请参阅下面 --left-right 选项描述中的示例)。但是,它会显示从另一个分支 cherry-picked 的提交(例如,“b 上的第 3 个”可能从分支 A cherry-picked)。使用此选项,此类提交对将从输出中排除。

--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 条目到较旧条目的 reflog 条目。使用此选项时,您不能指定要排除的提交(即,不能使用 ^commitcommit1..commit2commit1...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 中的第一个现有伪引用。仅当索引具有未合并的条目时才有效。此选项可用于在解决来自三方合并的冲突时显示相关提交。

--boundary

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

历史简化

有时候你可能只对历史记录的某些部分感兴趣,例如修改特定 <path> 的提交。但是,历史简化分为两个部分,一部分是选择提交,另一部分是如何进行简化,因为有各种策略来简化历史记录。

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

<路径>

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

--simplify-by-decoration

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

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

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

默认模式

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

--show-pulls

包括默认模式中的所有提交,以及所有对于第一个父级不是 TREESAME,但对于后续父级是 TREESAME 的合并提交。此模式有助于显示“首次引入”对分支的更改的合并提交。

--full-history

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

--dense

仅显示选定的提交,以及一些用于提供有意义的历史记录的提交。

--sparse

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

--simplify-merges

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

--ancestry-path[=<commit>]

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

下面是更详细的解释。

假设您指定 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。

  • Dfoo 设置为 “baz”。其合并 OND 中的字符串组合为 “foobarbaz”;也就是说,对于任何父级都不是 TREESAME。

  • Equux 更改为 “xyzzy”,其合并 P 将字符串组合为 “quux xyzzy”。P 对于 O 是 TREESAME,但对于 E 不是。

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

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

默认模式

如果提交对于任何父级都不是 TREESAME,则包含该提交(尽管这可以更改,请参阅下面的 --sparse)。如果提交是合并,并且对于一个父级是 TREESAME,则仅跟踪该父级。(即使有多个 TREESAME 父级,也仅跟踪其中一个。)否则,跟踪所有父级。

这导致

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

请注意,如果存在 TREESAME 父级,则仅跟踪 TREESAME 父级的规则如何完全从考虑中删除了 BC 通过 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 的父级 ICN 以及 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 的父列表类似地删除了 I。然后完全删除了 P,因为它有一个父级并且是 TREESAME。

  • Q 的父列表已将 Y 简化为 X。然后删除了 X,因为它是一个 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 中不存在的东西”的意义上讲。此示例中的结果将是所有提交,除了 AB(当然还有 D 本身)。

但是,当我们想要找出 M 中的哪些提交受到 D 引入的错误的影响并且需要修复时,我们可能只想查看 D..M 的子集,这些子集实际上是 D 的后代,即排除 CK。这正是 --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,它被 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 会遍历每条边。 这将发现提交 AB 以及合并 M,但也会显示合并提交 OP。 通过父级重写,生成的关系图是

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

在这里,合并提交 OP 会产生额外的噪音,因为它们实际上并没有对 file.txt 进行更改。 它们只是合并了一个基于旧版本 file.txt 的主题。 这是在使用工作流程的存储库中的一个常见问题,在这种工作流程中,许多贡献者并行工作并将其主题分支沿单个主干合并:许多不相关的合并出现在 --full-history 结果中。

当使用 --simplify-merges 选项时,提交 OP 会从结果中消失。 这是因为 OP 的重写后的第二个父节点可以从它们的第一个父节点访问。 这些边会被移除,然后这些提交看起来就像是与它们的父节点是 TREESAME 的单亲提交。 这也发生在提交 N 上,从而产生如下历史记录视图

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

在此视图中,我们看到了来自 ABX 的所有重要的单亲更改。 我们还看到了仔细解决的合并 M 和不太仔细解决的合并 R。 这通常足以确定为什么提交 AB 从默认视图中的历史记录中“消失”。 但是,这种方法存在一些问题。

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

第二个问题是审计。 当许多贡献者在同一个存储库上工作时,哪个合并提交将更改引入到重要的分支中非常重要。 上面有问题的合并 R 不太可能是用于合并到重要分支中的合并提交。 相反,合并 N 用于将 RX 合并到重要分支中。 此提交可能在其提交消息中包含有关为什么更改 X 会覆盖来自 AB 的更改的信息。

--show-pulls

除了默认历史记录中显示的提交之外,还显示每个与其第一个父节点不是 TREESAME 但与后面的父节点是 TREESAME 的合并提交。

当合并提交通过 --show-pulls 包含时,该合并被视为从另一个分支“拉取”了更改。 当在此示例中使用 --show-pulls(并且没有其他选项)时,生成的关系图是

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

在这里,合并提交 RN 被包括在内,因为它们分别将提交 XR 拉取到基本分支中。 这些合并是提交 AB 没有出现在默认历史记录中的原因。

--show-pulls--simplify-merges 配对时,该图包含所有必要的信息

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

请注意,由于可以从 R 访问 M,因此从 NM 的边已被简化。 但是,N 仍然作为重要的提交出现在历史记录中,因为它将更改 R “拉取”到主分支中。

--simplify-by-decoration 选项允许您仅查看历史记录拓扑的大局,方法是省略未被标签引用的提交。 如果 (1) 它们被标签引用,或者 (2) 它们更改了命令行上给定的路径的内容,则提交被标记为 !TREESAME(换句话说,在上面描述的历史记录简化规则之后保留)。 所有其他提交都被标记为 TREESAME(可以简化)。

映射作者

请参阅 gitmailmap[5]

请注意,如果在存储库外部运行 git shortlog(以处理标准输入上的日志内容),它将在当前目录中查找 .mailmap 文件。

GIT

属于 git[1] 套件的一部分

scroll-to-top