设置和配置
获取和创建项目
基本快照
分支和合并
共享和更新项目
检查和比较
补丁
调试
邮件
外部系统
服务器管理员
指南
管理
底层命令
- 2.45.1 → 2.47.0 无更改
- 2.45.0 04/29/24
- 2.43.3 → 2.44.2 无更改
- 2.43.2 02/13/24
- 2.43.1 无更改
- 2.43.0 11/20/23
- 2.42.1 → 2.42.3 无更改
- 2.42.0 08/21/23
- 2.41.1 → 2.41.2 无更改
- 2.41.0 06/01/23
- 2.40.1 → 2.40.3 无更改
- 2.40.0 03/12/23
- 2.39.1 → 2.39.5 无更改
- 2.39.0 12/12/22
- 2.38.1 → 2.38.5 无更改
- 2.38.0 10/02/22
- 2.37.1 → 2.37.7 无更改
- 2.37.0 06/27/22
- 2.36.1 → 2.36.6 无更改
- 2.36.0 04/18/22
- 2.35.1 → 2.35.8 无更改
- 2.35.0 01/24/22
- 2.33.3 → 2.34.8 无更改
- 2.33.2 03/23/22
- 2.33.1 10/12/21
- 2.33.0 08/16/21
- 2.32.1 → 2.32.7 无更改
- 2.32.0 06/06/21
- 2.31.1 → 2.31.8 无更改
- 2.31.0 03/15/21
- 2.30.1 → 2.30.9 无更改
- 2.30.0 12/27/20
- 2.29.1 → 2.29.3 无更改
- 2.29.0 10/19/20
- 2.27.1 → 2.28.1 无更改
- 2.27.0 06/01/20
- 2.25.1 → 2.26.3 无更改
- 2.25.0 01/13/20
- 2.18.1 → 2.24.4 无更改
- 2.18.0 06/21/18
- 2.13.7 → 2.17.6 无更改
- 2.12.5 09/22/17
- 2.1.4 → 2.11.4 无更改
- 2.0.5 12/17/14
概要
git shortlog [<options>] [<revision-range>] [[--] <path>…] git log --pretty=short | git shortlog [<options>]
描述
以适合包含在发行公告中的格式汇总 git log 输出。每个提交都将按作者和标题进行分组。
此外,将从提交描述中删除“[PATCH]”。
如果命令行上没有传递修订版本,并且标准输入不是终端或没有当前分支,则 git shortlog 将输出从标准输入读取的日志摘要,而不会引用当前存储库。
选项
- -n
- --numbered
-
根据每个作者的提交次数对输出进行排序,而不是按作者的字母顺序排序。
- -s
- --summary
-
抑制提交描述,仅提供提交计数摘要。
- -e
-
显示每个作者的电子邮件地址。
- --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] 的“提交格式”部分中的
--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>
标识。如果成功,则应用 mailmap 并省略电子邮件,除非指定了--email
选项。如果该值无法解析为标识,则将按字面意思和完整地采用它。
如果多次指定
--group
,则在每个值下计算提交(但同样,在该提交中每个唯一值仅计算一次)。例如,git shortlog --group=author --group=trailer:co-authored-by
同时计算作者和共同作者。 -
- -c
- --committer
-
这是
--group=committer
的别名。 - -w[<width>[,<indent1>[,<indent2>]]]
-
通过在
width
处换行来换行输出。每个条目的第一行缩进indent1
个空格,第二行及后续行缩进indent2
个空格。width
、indent1
和indent2
分别默认为 76、6 和 9。如果 width 为
0
(零),则缩进输出的行而不换行。 - <revision-range>
-
仅显示指定修订版本范围内的提交。当未指定 <revision-range> 时,它默认为
HEAD
(即导致当前提交的整个历史记录)。origin..HEAD
指定可从当前提交(即HEAD
)到达的所有提交,但不能从origin
到达。有关 <revision-range> 的完整拼写方式列表,请参阅 gitrevisions[7] 的“指定范围”部分。 - [--] <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
给出所有八爪鱼合并。--no-min-parents
和--no-max-parents
再次重置这些限制(无限制)。等效形式为--min-parents=0
(任何提交都有 0 个或更多父级)和--max-parents=-1
(负数表示没有上限)。 - --first-parent
-
在查找要包含的提交时,在看到合并提交时仅遵循第一个父级提交。当查看特定主题分支的演变时,此选项可以提供更好的概述,因为合并到主题分支中往往只是为了不时地调整到更新的上游,并且此选项允许您忽略合并到您的历史记录中的各个提交。
- --exclude-first-parent-only
-
在查找要排除的提交(使用 ^)时,在看到合并提交时仅遵循第一个父级提交。这可以用来查找主题分支中从其与远程分支分叉的那一点开始的更改集,因为任意合并可以是有效的主题分支更改。
- --not
-
反转所有后续修订规范(直至下一个
--not
)的 ^ 前缀(或缺少前缀)的含义。当在命令行上用于--stdin
之前时,通过标准输入传递的修订不会受其影响。相反,当通过标准输入传递时,命令行上传递的修订不会受其影响。 - --all
-
假装
refs/
中的所有引用以及HEAD
都在命令行上列出为 <commit>。 - --branches[=<pattern>]
-
假装
refs/heads
中的所有引用都在命令行上列出为 <commit>。如果给出了 <pattern>,则将分支限制为与给定 shell 通配符匹配的分支。如果模式缺少 ?、* 或 [,则隐含结尾处的 /*。 - --tags[=<pattern>]
-
假装
refs/tags
中的所有引用都在命令行上列出为 <commit>。如果给出了 <pattern>,则将标签限制为与给定 shell 通配符匹配的标签。如果模式缺少 ?、* 或 [,则隐含结尾处的 /*。 - --remotes[=<pattern>]
-
假装
refs/remotes
中的所有引用都在命令行上列出为 <commit>。如果给出了 <pattern>,则将远程跟踪分支限制为与给定 shell 通配符匹配的分支。如果模式缺少 ?、* 或 [,则隐含结尾处的 /*。 - --glob=<glob-pattern>
-
假装所有与 shell 通配符 <glob-pattern> 匹配的引用都在命令行上列出为 <commit>。如果缺少,则会自动添加前导 refs/。如果模式缺少 ?、* 或 [,则隐含结尾处的 /*。
- --exclude=<glob-pattern>
-
不包含与 <glob-pattern> 匹配的引用,否则下一个
--all
、--branches
、--tags
、--remotes
或--glob
会考虑这些引用。此选项的重复会累积排除模式,直到下一个--all
、--branches
、--tags
、--remotes
或--glob
选项(其他选项或参数不会清除累积的模式)。当分别应用于
--branches
、--tags
或--remotes
时,给定的模式不应以refs/heads
、refs/tags
或refs/remotes
开头,并且当应用于--glob
或--all
时,它们必须以refs/
开头。如果需要尾随 /*,则必须明确给出。 -
不包含将被
git-fetch
、git-receive-pack
或git-upload-pack
隐藏的引用,方法是查询相应的fetch.hideRefs
、receive.hideRefs
或uploadpack.hideRefs
配置以及transfer.hideRefs
(参见 git-config[1])。此选项会影响下一个伪引用选项--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
-
假装错误的二分查找 ref
refs/bisect/bad
已列出,并且假装它后面跟着--not
和良好的二分查找 refrefs/bisect/good-*
在命令行上。 - --stdin
-
除了从命令行获取参数外,还从标准输入读取它们。这接受提交和伪选项,如
--all
和--glob=
。当看到--
分隔符时,以下输入将被视为路径并用于限制结果。通过标准输入读取的标志(如--not
)仅对以相同方式传递的参数有效,并且不会影响任何后续的命令行参数。 - --cherry-mark
-
类似于
--cherry-pick
(见下文),但用=
标记等效的提交而不是省略它们,用+
标记不等效的提交。 - --cherry-pick
-
当使用对称差集限制提交集时,省略任何引入与“另一侧”上的另一个提交相同的更改的提交。
例如,如果您有两个分支
A
和B
,则列出它们一侧的所有提交的常用方法是使用--left-right
(请参见--left-right
选项说明中的以下示例)。但是,它显示了从另一个分支中挑选的提交(例如,“b 上的第 3 个”可能从分支 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
格式(除了oneline
和reference
之外,出于显而易见的原因),这会导致输出包含从 reflog 中获取的两行额外信息。输出中的 reflog 指定符可以显示为ref@{<Nth>}
(其中 <Nth> 是 reflog 中的反时间顺序索引)或ref@{<timestamp>}
(使用该条目的 <timestamp>),具体取决于一些规则-
如果起点指定为
ref@{<Nth>}
,则显示索引格式。 -
如果起点指定为
ref@{now}
,则显示时间戳格式。 -
如果没有使用两者,但命令行上给出了
--date
,则以--date
请求的格式显示时间戳。 -
否则,显示索引格式。
在
--pretty=oneline
下,提交消息在同一行中以此信息为前缀。此选项不能与--reverse
结合使用。另请参见 git-reflog[1]。在
--pretty=reference
下,此信息根本不会显示。 -
- --merge
-
显示在范围
HEAD...<other>
中触及冲突路径的提交,其中<other>
是MERGE_HEAD
、CHERRY_PICK_HEAD
、REVERT_HEAD
或REBASE_HEAD
中第一个存在的伪引用。仅在索引具有未合并的条目时有效。此选项可用于在解决来自三方合并的冲突时显示相关提交。 - --boundary
-
输出排除的边界提交。边界提交以
-
为前缀。
历史简化
有时你只对历史的一部分感兴趣,例如修改特定<path>的提交。但是历史简化有两个部分,一部分是选择提交,另一部分是如何进行选择,因为有多种简化历史的策略。
以下选项选择要显示的提交
请注意,可能会显示额外的提交以提供有意义的历史。
以下选项会影响简化执行的方式
- 默认模式
-
将历史简化为解释树最终状态的最简单历史。之所以是最简单的,是因为如果最终结果相同(即合并具有相同内容的分支),它会修剪一些分支。
- --show-pulls
-
包含默认模式下的所有提交,以及任何对第一个父节点不是TREESAME但对后续父节点是TREESAME的合并提交。此模式有助于显示“首次引入”更改到分支的合并提交。
- --full-history
-
与默认模式相同,但不修剪某些历史记录。
- --dense
-
仅显示选定的提交,以及一些提供有意义的历史记录的提交。
- --sparse
-
显示简化历史记录中的所有提交。
- --simplify-merges
-
--full-history
的附加选项,用于从结果历史记录中删除一些不必要的合并,因为没有选定的提交对该合并有贡献。 - --ancestry-path[=<commit>]
-
当给定要显示的提交范围(例如commit1..commit2或commit2 ^commit1)时,仅显示该范围内为<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。 -
D
将foo
设置为“baz”。它的合并O
将N
和D
中的字符串组合成“foobarbaz”;即,它对任何父节点都不是TREESAME。 -
E
将quux
更改为“xyzzy”,其合并P
将字符串组合成“quux xyzzy”。P
对O
是TREESAME,但对E
不是。 -
X
是一个独立的根提交,它添加了一个新文件side
,而Y
修改了它。Y
对X
是TREESAME。它的合并Q
将side
添加到P
中,并且Q
对P
是TREESAME,但对Y
不是。
rev-list
向后遍历历史记录,根据是否使用--full-history
和/或父重写(通过--parents
或--children
)来包含或排除提交。以下设置可用。
- 默认模式
-
如果提交对任何父节点都不是TREESAME,则包含该提交(尽管这可以更改,请参见下面的
--sparse
)。如果提交是合并,并且它对一个父节点是TREESAME,则仅遵循该父节点。(即使有多个TREESAME父节点,也只遵循其中一个。)否则,遵循所有父节点。这将导致
.-A---N---O / / / I---------D
请注意,仅遵循TREESAME父节点(如果可用)的规则完全排除了
B
。通过N
考虑了C
,但它是TREESAME。根提交与空树进行比较,因此I
为!TREESAME。父/子关系仅在使用
--parents
时可见,但这不会影响默认模式下选择的提交,因此我们显示了父行。 - --full-history 无父重写
-
此模式与默认模式在一个方面有所不同:始终遵循合并的所有父节点,即使它对其中一个父节点是TREESAME。即使合并的多个方面都有包含的提交,但这并不意味着合并本身是!在示例中,我们得到
I A B N D O P Q
M
被排除在外,因为它对两个父节点都是TREESAME。E
、C
和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
也发生了同样的情况。
除了上述设置之外,你还可以更改TREESAME是否影响包含
- --dense
-
如果遍历的提交对任何父节点都不是TREESAME,则包含该提交。
- --sparse
-
包含所有遍历的提交。
请注意,如果没有
--full-history
,这仍然会简化合并:如果其中一个父节点是TREESAME,我们只遵循那个父节点,因此合并的其他方面永远不会被遍历。 - --simplify-merges
-
首先,以与带父重写的
--full-history
相同的方式构建历史图(见上文)。然后根据以下规则将每个提交
C
简化为其在最终历史记录中的替换C'
-
将
C'
设置为C
。 -
用其简化后的
P'
替换C'
的每个父节点P
。在此过程中,删除是其他父节点的祖先或对空树是TREESAME的根提交的父节点,并删除重复项,但注意永远不要删除我们对它为TREESAME的所有父节点。 -
如果在此父重写之后,
C'
是根或合并提交(具有零个或>1个父节点)、边界提交或!TREESAME,则它将保留。否则,它将替换为其唯一的父节点。
通过与带父重写的
--full-history
进行比较,可以最好地显示其效果。示例变为.-A---M---N---O / / / I B D \ / / `---------'
请注意
N
、P
和Q
与--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计算<commit>的祖先提交集,但排除<commit>的祖先提交。这对于查看自
D
以来导致M
的历史记录发生了什么很有用,从“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--'
在这个例子中,假设我创建了file.txt
文件,并且A
、B
和X
分别以不同的方式修改了它。单亲提交C
、Z
和Y
没有更改file.txt
。合并提交M
是通过解决合并冲突创建的,它包含了来自A
和B
的更改,因此与两者都不相同(TREESAME)。但是,合并提交R
是通过忽略M
处file.txt
的内容,并只获取X
处file.txt
的内容创建的。因此,R
与X
相同(TREESAME),但与M
不同。最后,创建N
的自然合并解决方案是获取R
处file.txt
的内容,所以N
与R
相同(TREESAME),但与C
不同。合并提交O
和P
与它们的第一个父节点相同(TREESAME),但分别与它们的第二个父节点Z
和Y
不同。
使用默认模式时,N
和R
都具有一个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
不太可能是用于合并到重要分支的合并提交。相反,合并N
用于将R
和X
合并到重要分支中。此提交可能在其提交消息中包含有关为什么更改X
会覆盖来自A
和B
的更改的信息。
- --show-pulls
-
除了默认历史记录中显示的提交外,还显示每个与第一个父节点不相同(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(可能会被简化掉)。
映射作者
请参阅gitmailmap[5]。
请注意,如果在存储库外部运行git shortlog
(以处理标准输入上的日志内容),它将在当前目录中查找.mailmap
文件。
GIT
git[1]套件的一部分