设置和配置
获取和创建项目
基本快照
分支与合并
共享和更新项目
检查和比较
打补丁
调试
电子邮件
外部系统
服务器管理
指南
管理
底层命令
- 2.50.1 无更改
-
2.50.0
2025-06-16
- 2.49.1 无更改
-
2.49.0
2025-03-14
- 2.48.1 → 2.48.2 无更改
-
2.48.0
2025-01-10
- 2.46.1 → 2.47.3 无更改
-
2.46.0
2024-07-29
- 2.45.4 无更改
-
2.45.3
2024-11-26
- 2.45.1 → 2.45.2 无更改
-
2.45.0
2024-04-29
- 2.44.1 → 2.44.4 无更改
-
2.44.0
2024-02-23
- 2.43.3 → 2.43.7 无变更
-
2.43.2
2024-02-13
- 2.43.1 无变更
-
2.43.0
2023-11-20
- 2.42.2 → 2.42.4 无更改
-
2.42.1
2023-11-02
-
2.42.0
2023-08-21
- 2.41.1 → 2.41.3 无更改
-
2.41.0
2023-06-01
- 2.40.1 → 2.40.4 无更改
-
2.40.0
2023-03-12
- 2.39.1 → 2.39.5 无变化
-
2.39.0
2022-12-12
- 2.38.3 → 2.38.5 无更改
-
2.38.2
2022-12-11
- 2.38.1 无更改
-
2.38.0
2022-10-02
- 2.37.1 → 2.37.7 无更改
-
2.37.0
2022-06-27
- 2.36.1 → 2.36.6 无更改
-
2.36.0
2022-04-18
- 2.35.1 → 2.35.8 无更改
-
2.35.0
2022-01-24
- 2.33.3 → 2.34.8 无变更
-
2.33.2
2022-03-23
-
2.33.1
2021-10-12
-
2.33.0
2021-08-16
- 2.32.1 → 2.32.7 无变更
-
2.32.0
2021-06-06
- 2.31.1 → 2.31.8 无更改
-
2.31.0
2021-03-15
- 2.30.1 → 2.30.9 无更改
-
2.30.0
2020-12-27
- 2.29.1 → 2.29.3 无更改
-
2.29.0
2020-10-19
- 2.28.1 无更改
-
2.28.0
2020-07-27
- 2.27.1 无更改
-
2.27.0
2020-06-01
- 2.26.1 → 2.26.3 无更改
-
2.26.0
2020-03-22
- 2.25.2 → 2.25.5 无更改
-
2.25.1
2020-02-17
-
2.25.0
2020-01-13
- 2.24.1 → 2.24.4 无更改
-
2.24.0
2019-11-04
- 2.23.1 → 2.23.4 无更改
-
2.23.0
2019-08-16
- 2.22.1 → 2.22.5 无更改
-
2.22.0
2019-06-07
- 2.21.1 → 2.21.4 无更改
-
2.21.0
2019-02-24
- 2.20.1 → 2.20.5 无更改
-
2.20.0
2018-12-09
- 2.19.3 → 2.19.6 无更改
-
2.19.2
2018-11-21
- 2.19.1 无更改
-
2.19.0
2018-09-10
- 2.18.1 → 2.18.5 无更改
-
2.18.0
2018-06-21
- 2.17.1 → 2.17.6 无更改
-
2.17.0
2018-04-02
-
2.16.6
2019-12-06
-
2.15.4
2019-12-06
-
2.14.6
2019-12-06
-
2.13.7
2018-05-22
-
2.12.5
2017-09-22
-
2.11.4
2017-09-22
-
2.10.5
2017-09-22
-
2.9.5
2017-07-30
-
2.8.6
2017-07-30
-
2.7.6
2017-07-30
-
2.6.7
2017-05-05
-
2.5.6
2017-05-05
-
2.4.12
2017-05-05
-
2.3.10
2015-09-28
-
2.2.3
2015-09-04
-
2.1.4
2014-12-17
-
2.0.5
2014-12-17
描述
显示提交日志。
列出通过遵循给定提交的 parent
链接可达的提交,但排除那些前面带有 ^ 的提交可达的提交。默认情况下,输出按倒序时间顺序给出。
你可以将其视为一个集合操作。从命令行上给出的任何提交可达的提交形成一个集合,然后从前面带有 ^ 的提交可达的提交将从该集合中减去。剩余的提交就是命令的输出结果。还可以使用各种其他选项和路径参数来进一步限制结果。
因此,以下命令
$ git log foo bar ^baz
表示“列出所有可从 foo 或 bar 到达,但不可从 baz 到达的提交”。
特殊符号“<commit1>..<commit2>”可用作“^<commit1> <commit2>”的简写。例如,以下任一形式都可以互换使用
$ git log origin..HEAD $ git log HEAD ^origin
另一个特殊符号是“<commit1>…<commit2>”,这对于合并很有用。产生的提交集合是两个操作数之间的对称差异。以下两个命令是等效的
$ git log A B --not $(git merge-base --all A B) $ git log A...B
此命令接受适用于 git-rev-list[1] 命令的选项,以控制显示内容和方式,以及适用于 git-diff[1] 命令的选项,以控制如何显示每个提交引入的更改。
选项
- --follow
-
继续列出文件重命名后的历史(仅适用于单个文件)。
- --no-decorate
- --decorate[=short|full|auto|no]
-
打印出所显示任何提交的引用名称。如果指定 short,则不打印引用名称前缀 refs/heads/、refs/tags/ 和 refs/remotes/。如果指定 full,则打印完整的引用名称(包括前缀)。如果指定 auto,则如果输出到终端,引用名称将像指定 short 一样显示,否则不显示引用名称。选项
--decorate
是--decorate=short
的简写。如果已配置,则默认为log.decorate
的配置值,否则默认为auto
。 - --decorate-refs=<pattern>
- --decorate-refs-exclude=<pattern>
-
对于每个候选引用,如果它与提供给
--decorate-refs-exclude
的任何模式匹配,或者它不与提供给--decorate-refs
的任何模式匹配,则不将其用于装饰。log.excludeDecoration
配置选项允许从装饰中排除引用,但显式的--decorate-refs
模式将覆盖log.excludeDecoration
中的匹配项。如果没有给出这些选项或配置设置,那么如果引用匹配
HEAD
、refs/heads/
、refs/remotes/
、refs/stash/
或refs/tags/
,则将它们用作装饰。 - --clear-decorations
-
指定此选项时,它会清除所有以前的
--decorate-refs
或--decorate-refs-exclude
选项,并放宽默认装饰过滤器以包含所有引用。如果配置值log.initialDecorationSet
设置为all
,则假定此选项。 - --source
-
打印出命令行上给出的、通过它到达每个提交的引用名称。
- --[no-]mailmap
- --[no-]use-mailmap
-
使用 mailmap 文件将作者和提交者姓名及电子邮件地址映射到规范的真实姓名和电子邮件地址。参见 git-shortlog[1]。
- --full-diff
-
如果没有此标志,
git
log
-p
<path>... 会显示修改了指定路径的提交,以及关于相同指定路径的差异。有了此标志,对于修改了指定路径的提交,将显示完整的差异;这意味着“<path>…”只限制提交,而不限制这些提交的差异。请注意,这会影响所有基于差异的输出类型,例如
--stat
等产生的输出。 - --log-size
-
在每个提交的输出中包含一行“log size <number>”,其中 <number> 是该提交消息的字节长度。旨在通过允许工具预先分配空间来加快从
git
log
输出中读取日志消息的工具的速度。 - -L<start>,<end>:<file>
- -L:<funcname>:<file>
-
跟踪由 <start>,<end> 或函数名正则表达式 <funcname> 在 <file> 中给出的行范围的演变。您不能给出任何路径规范限制符。这目前仅限于从单个修订开始的遍历,即,您只能给出零个或一个正修订参数,并且 <start> 和 <end>(或 <funcname>)必须存在于起始修订中。您可以多次指定此选项。这意味着
--patch
。补丁输出可以使用--no-patch
抑制,但其他差异格式(即--raw
、--numstat
、--shortstat
、--dirstat
、--summary
、--name-only
、--name-status
、--check
)目前尚未实现。<start> 和 <end> 可以采用以下形式之一
-
数字
如果 <start> 或 <end> 是一个数字,它指定一个绝对行号(行从 1 开始计数)。
-
/正则表达式/
此形式将使用与给定 POSIX 正则表达式匹配的第一行。如果 <start> 是一个正则表达式,它将从上一个
-L
范围的末尾开始搜索(如果存在),否则从文件开头开始搜索。如果 <start> 是^/regex/
,它将从文件开头开始搜索。如果 <end> 是一个正则表达式,它将从 <start> 给定的行开始搜索。 -
+偏移量 或 -偏移量
这仅对 <end> 有效,并将指定 <start> 给定行之前或之后的行数。
如果用
:
<funcname> 替换 <start> 和 <end>,它是一个正则表达式,表示从第一个匹配 <funcname> 的函数名行到下一个函数名行的范围。:
<funcname> 从上一个-L
范围的末尾开始搜索(如果存在),否则从文件开头开始搜索。^:
<funcname> 从文件开头开始搜索。函数名确定方式与git
diff
处理补丁块头(参见 gitattributes[5] 中 Defining a custom hunk-header)的方式相同。 -
- <revision-range>
-
仅显示指定修订范围内的提交。如果没有指定 <revision-range>,则默认为
HEAD
(即,导致当前提交的整个历史记录)。origin..HEAD
指定了从当前提交(即HEAD
)可达的所有提交,但不包括从origin
可达的提交。有关拼写 <revision-range> 的完整列表,请参阅 gitrevisions[7] 的 Specifying Ranges 部分。 - [--] <path>…
-
只显示足以解释指定路径匹配文件是如何产生的提交。有关详细信息和其他简化模式,请参见下面的 History Simplification。
当出现混淆时,路径可能需要在前面加上
--
,以将其与选项或修订范围分开。
提交限制
除了使用描述中解释的特殊符号指定应列出的提交范围外,还可以应用额外的提交限制。
使用更多选项通常会进一步限制输出(例如,--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>
-
限制提交输出为引用日志条目与指定模式(正则表达式)匹配的提交。当有多个
--grep-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
-
在查找要包含的提交时,遇到合并提交时只遵循第一个父提交。此选项在查看特定主题分支的演变时可以提供更好的概览,因为合并到主题分支通常只是为了适应上游的更新,此选项允许您忽略此类合并带入您历史中的单个提交。
此选项还会将合并提交的默认差异格式更改为
first-parent
,详细信息请参阅--diff-merges=first-parent
。 - --exclude-first-parent-only
-
在查找要排除的提交(带 ^)时,遇到合并提交时只遵循第一个父提交。这可用于查找主题分支中从其与远程分支分歧点开始的更改集,因为任意合并都可以是有效的主题分支更改。
- --not
-
反转所有后续修订说明符的 ^ 前缀(或其缺失)的含义,直到下一个
--not
。在命令行上 --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>
-
不包含与 <glob-pattern> 匹配的引用,否则下一个
--all
、--branches
、--tags
、--remotes
或--glob
将会考虑这些引用。此选项的重复使用会累积排除模式,直到下一个--all
、--branches
、--tags
、--remotes
或--glob
选项(其他选项或参数不会清除累积的模式)。给定模式应用于
--branches
、--tags
或--remotes
时,不应以refs/heads
、refs/tags
或refs/remotes
开头;应用于--glob
或--all
时,必须以refs/
开头。如果意图使用尾随的 /*,则必须明确给出。 -
通过查阅相应的
fetch.hideRefs
、receive.hideRefs
或uploadpack.hideRefs
配置以及transfer.hideRefs
(参见 git-config[1]),不包含会被git-fetch
、git-receive-pack
或git-upload-pack
隐藏的引用。此选项影响下一个伪引用选项--all
或--glob
,并在处理它们后清除。 - --reflog
-
假装引用日志中提及的所有对象都作为 <commit> 列在命令行上。
- --alternate-refs
-
假装所有在备用仓库中作为引用尖端提及的对象都列在命令行上。备用仓库是指其对象目录在
objects/info/alternates
中指定的任何仓库。包含的对象集可能会被core.alternateRefsCommand
等修改。参见 git-config[1]。 - --single-worktree
-
默认情况下,当存在多个工作树时(参见 git-worktree[1]),以下选项将检查所有工作树:
--all
、--reflog
和--indexed-objects
。此选项强制它们只检查当前工作树。 - --ignore-missing
-
在输入中遇到无效对象名称时,假装没有给出错误的输入。
- --bisect
-
假装坏的二分查找引用
refs/bisect/bad
已列出,并且其后跟着--not
和好的二分查找引用refs/bisect/good-*
在命令行上。 - --stdin
-
除了从命令行获取参数外,也从标准输入读取参数。这接受提交和伪选项,如
--all
和--glob=
。当看到--
分隔符时,后续输入将被视为路径并用于限制结果。通过标准输入读取的标志(如--not
)仅对以相同方式传递的参数有效,并且不会影响任何后续命令行参数。 - --cherry-mark
-
类似于
--cherry-pick
(见下文),但用=
标记等效提交而不是省略它们,用+
标记不等效提交。 - --cherry-pick
-
当提交集合通过对称差异限制时,省略与“另一侧”的另一个提交引入相同更改的任何提交。
例如,如果您有两个分支,
A
和B
,列出其中一侧的所有提交的常用方法是使用--left-right
(参见下面--left-right
选项描述中的示例)。但是,它会显示从另一个分支拣选(cherry-picked)的提交(例如,“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
-
不遍历提交祖先链,而是从最新引用日志条目遍历到较旧条目。使用此选项时,不能指定要排除的提交(即,不能使用 ^commit、commit1..commit2 和 commit1...commit2 符号)。
除了
oneline
和reference
之外(出于显而易见的原因),使用--pretty
格式时,这将导致输出包含取自引用日志的两行额外信息。输出中的引用日志指示符可以显示为ref@{
<Nth>}
(其中 <Nth> 是引用日志中的倒序时间索引)或显示为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
过滤的差异中,它们分别看起来不同和相同。)
在下文中,我们将始终引用相同的历史示例来阐述简化设置之间的差异。我们假设您正在此提交图中过滤文件 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
。C
是通过N
考虑的,但它是 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
。 -
将
C'
的每个父提交P
替换为其简化版本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 计算
M
的祖先提交集合,但排除D
的祖先提交。这对于查看自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 \ 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
,它被 A
、B
和 X
以不同方式修改。单父提交 C
、Z
和 Y
不改变 file.txt
。合并提交 M
是通过解决合并冲突以包含来自 A
和 B
的更改而创建的,因此它与两者都不属于 TREESAME。然而,合并提交 R
是通过忽略 M
处的 file.txt
内容并只取 X
处的 file.txt
内容而创建的。因此,R
与 X
属于 TREESAME 但不与 M
属于 TREESAME。最后,创建 N
的自然合并解决方案是取 R
处的 file.txt
内容,因此 N
与 R
属于 TREESAME 但不与 C
属于 TREESAME。合并提交 O
和 P
与它们的第一父提交属于 TREESAME,但不与它们的第二父提交 Z
和 Y
属于 TREESAME。
当使用默认模式时,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 但与后来的某个父提交属于 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(可能会被简化掉)。
提交排序
默认情况下,提交按逆时间顺序显示。
- --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
结合使用。
提交格式化
- --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>" 选项(如果显示差异输出,此选项也会对其进行修改)来指定前缀的最小长度。
这应该会使使用 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)中,制表符会被扩展。
- --notes[=<ref>]
-
当显示提交日志消息时,显示注释提交的注解(参见 git-notes[1])。当命令行中没有给出
--pretty
、--format
或--oneline
选项时,这是git
log
、git
show
和git
whatchanged
命令的默认行为。默认情况下,显示的注解来自
core.notesRef
和notes.displayRef
变量中列出的注解引用(或相应的环境变量覆盖)。有关更多详细信息,请参阅 git-config[1]。如果带有可选的 <ref> 参数,则使用该引用来查找要显示的注解。当引用以
refs/notes/
开头时,它可以指定完整的引用名称;当它以notes/
开头时,以refs/
为前缀,否则以refs/notes/
为前缀来形成引用的完整名称。多个 --notes 选项可以组合使用以控制显示哪些注解。示例:"--notes=foo" 将只显示来自 "refs/notes/foo" 的注解;"--notes=foo --notes" 将显示来自 "refs/notes/foo" 和默认注解引用(一个或多个)的注解。
- --no-notes
-
不显示注解。这会通过重置显示注解的引用列表来抵消上述
--notes
选项。选项按照命令行上给出的顺序解析,因此例如 "--notes --notes=foo --no-notes --notes=bar" 将只显示来自 "refs/notes/bar" 的注解。 - --show-notes-by-default
-
显示默认注解,除非给出了显示特定注解的选项。
- --show-notes[=<ref>]
- --[no-]standard-notes
-
这些选项已弃用。请改用上面的 --notes/--no-notes 选项。
- --show-signature
-
通过将签名传递给
gpg
--verify
并显示输出来检查已签名提交对象的有效性。 - --relative-date
-
等同于
--date=relative
。 - --date=<format>
-
仅对以人类可读格式显示的日期生效,例如使用
--pretty
时。log.date
配置变量设置了 log 命令的--date
选项的默认值。默认情况下,日期以原始时区(提交者或作者的时区)显示。如果将-local
附加到格式(例如iso-local
),则使用用户的本地时区。--date=relative
显示相对于当前时间的日期,例如“2 hours ago”。-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
将日期显示为自 epoch(1970-01-01 00:00:00 UTC)以来的秒数,后跟一个空格,然后是作为 UTC 偏移量的时区(一个带四个数字的+
或-
;前两位是小时,后两位是分钟)。即,如同时间戳用strftime
("%s
%z"
) 格式化一样。请注意,-local
选项不影响自 epoch 以来的秒数值(该值始终以 UTC 衡量),但会切换随附的时区值。--date=human
在时区与当前时区不匹配时显示时区,如果匹配则不打印整个日期(即,对于“今年”的日期跳过打印年份,但如果日期在最近几天并且我们可以直接说出是星期几,则跳过整个日期本身)。对于较旧的日期,小时和分钟也被省略。--date=unix
将日期显示为 Unix epoch 时间戳(自 1970 年以来的秒数)。与--raw
一样,这始终是 UTC 时间,因此-local
没有效果。--date=format:...
将格式 ... 传递给您的系统strftime
函数,但 %s、%z 和 %Z 除外,它们在内部处理。使用--date=format:%c
以您系统区域设置的首选格式显示日期。有关格式占位符的完整列表,请参阅strftime
手册。当使用-local
时,正确的语法是--date=format-local:...
。--date=default
是默认格式,基于 ctime(3) 输出。它显示一行,包含三字母的星期几、三字母的月份、日期、"HH:MM:SS" 格式的小时-分钟-秒,后跟四位数年份,以及时区信息,除非使用本地时区,例如Thu
Jan
1
00:00:00
1970
+0000
。 -
- --parents
-
同时打印提交的父提交(格式为 "commit parent…")。也启用父提交重写,参见上文的 历史简化。
- --children
-
同时打印提交的子提交(格式为 "commit child…")。也启用父提交重写,参见上文的 历史简化。
- --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>,则它是将代替默认分隔符显示的字符串。
美观格式 (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=short
格式化,除非明确指定了另一个--date
选项。与任何带有格式占位符的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 信息显示的是真实的父提交,不考虑嫁接或历史简化。请注意,此格式影响提交的显示方式,但不影响差异的显示方式,例如使用
git
log
--raw
。要在原始差异格式中获取完整的对象名称,请使用--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.<<
占位符有
-
扩展为单个文字字符的占位符
-
影响后续占位符格式的占位符
- %Cred
-
切换颜色为红色
- %Cgreen
-
切换颜色为绿色
- %Cblue
-
切换颜色为蓝色
- %Creset
-
重置颜色
- %C(…)
-
颜色规范,如 git-config[1] 的“配置文件”部分的“值”下所述。默认情况下,颜色仅在为日志输出启用时(通过
color.diff
、color.ui
或--color
,并且如果我们将输出到终端,则遵循前者的auto
设置)才显示。%C
(auto,...
) 被接受为默认值的历史同义词(例如%C
(auto,red
))。指定%C
(always,...
) 将即使在颜色未被启用时也显示颜色(但考虑直接使用--color=always
来为整个输出启用颜色,包括此格式和 Git 可能着色的任何其他内容)。单独的auto
(即%C
(auto
))将在下一个占位符上启用自动着色,直到颜色再次切换。 - %m
-
左 (<)、右 (>) 或边界 (
-
) 标记 - %w([<w>[,<i1>[,<i2>]]])
-
切换行回绕,类似于 git-shortlog[1] 的 -w 选项。
- %<( <N> [,trunc|ltrunc|mtrunc])
-
使下一个占位符至少占据 N 列宽度,如有必要,在右侧填充空格。如果输出长于 N 列,可选地在左侧(ltrunc)使用省略号 .. 截断
..ft
,在中间(mtrunc)截断mi..le
,或在末尾(trunc)截断rig..
。注意1:截断仅在 N >= 2 时正确工作。注意2:N 和 M 值(见下文)周围的空格是可选的。注意3:表情符号和其他宽字符将占据两个显示列,这可能超出列边界。注意4:分解字符组合标记可能在填充边界处错位。 - %<|( <M> )
-
使下一个占位符至少占据到第 M 个显示列,如有必要,在右侧填充空格。使用负值 M 表示从终端窗口右侧边缘测量的列位置。
- %>( <N> ), %>|( <M> )
-
分别类似于 %<( <N> )、%<|( <M> ),但在左侧填充空格
- %>>( <N> ), %>>|( <M> )
-
分别类似于 %>( <N> )、%>|( <M> ),但如果下一个占位符占用的空间多于给定空间且其左侧有空格,则使用这些空格
- %><( <N> ), %><|( <M> )
-
分别类似于 %<( <N> )、%<|( <M> ),但填充两侧(即文本居中)
-
展开为从提交中提取的信息的占位符
- %H
-
提交哈希
- %h
-
缩写提交哈希
- %T
-
树哈希
- %t
-
缩写树哈希
- %P
-
父哈希
- %p
-
缩写父哈希
- %an
-
作者姓名
- %aN
-
作者姓名(遵循 .mailmap,参见 git-shortlog[1] 或 git-blame[1])
- %ae
-
作者电子邮件
- %aE
-
作者电子邮件(遵循 .mailmap,参见 git-shortlog[1] 或 git-blame[1])
- %al
-
作者电子邮件本地部分(@ 符号之前的部分)
- %aL
-
作者本地部分(参见 %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[:<options>])
-
带有自定义装饰的引用名称。
decorate
字符串后面可以跟一个冒号和零个或多个逗号分隔的选项。选项值可以包含字面格式代码。由于其在选项语法中的作用,必须使用这些代码来表示逗号 (%x2C
) 和右括号 (%x29
)。-
prefix=<value>:在引用名称列表之前显示。默认为 " ("。
-
suffix=<value>:在引用名称列表之后显示。默认为 ")"。
-
separator=<value>:在引用名称之间显示。默认为 "
,
"。 -
pointer=<value>:如果 HEAD 指向某个分支,则在 HEAD 和该分支之间显示。默认为 " -> "。
-
tag=<value>:在标签名称之前显示。默认为 "
tag:
"。
-
例如,生成不带包裹或标签注释的装饰,并使用空格作为分隔符
+
%
(decorate:prefix=,suffix=,tag=,separator=
)- %(describe[:<options>])
-
人类可读的名称,类似于 git-describe[1];对于不可描述的提交,为空字符串。
describe
字符串后面可以跟一个冒号和零个或多个逗号分隔的选项。当同时添加或删除标签时,描述可能不一致。-
tags[=<bool-value>]:除了只考虑带注释的标签,也考虑轻量级标签。
-
abbrev=<number>:不使用缩写对象名称的默认十六进制数字位数(将根据仓库中的对象数量而变化,默认值为 7),而是使用 <number> 位数,或者根据需要使用足够的位数来形成唯一的对象名称。
-
match=<pattern>:只考虑匹配给定
glob
(7
) 模式的标签,不包括 "refs/tags/" 前缀。 -
exclude=<pattern>:不考虑匹配给定
glob
(7
) 模式的标签,不包括 "refs/tags/" 前缀。
-
- %S
-
在命令行上给出的引用名称,通过它到达了提交(如
git
log
--source
),仅适用于git
log
- %e
-
编码
- %s
-
主题
- %f
-
净化后的主题行,适合作为文件名
- %b
-
正文
- %B
-
原始正文(未回绕的主题和正文)
- %N
-
提交注释
- %GG
-
来自 GPG 的原始验证消息,用于已签名提交
- %G?
-
对于有效签名显示 "G",对于无效签名显示 "B",对于有效但未知有效性的签名显示 "U",对于已过期的有效签名显示 "X",对于由已过期密钥创建的有效签名显示 "Y",对于由已撤销密钥创建的有效签名显示 "R",如果无法检查签名(例如缺少密钥)显示 "E",如果没有签名显示 "N"
- %GS
-
显示已签名提交的签名者姓名
- %GK
-
显示用于签署已签名提交的密钥
- %GF
-
显示用于签署已签名提交的密钥指纹
- %GP
-
显示其子密钥用于签署已签名提交的主密钥指纹
- %GT
-
显示用于签署已签名提交的密钥的信任级别
- %gD
-
引用日志选择器,例如
refs/stash@{1}
或refs/stash@{2
minutes
ago}
;格式遵循-g
选项描述的规则。@
之前的部分是命令行上给出的引用名称(因此git
log
-g
refs/heads/master
将产生refs/heads/master@{0}
)。 - %gd
-
缩短的引用日志选择器;与
%gD
相同,但引用名称部分被缩短以提高人类可读性(因此refs/heads/master
变为master
)。 - %gn
-
引用日志身份名称
- %gN
-
引用日志身份名称(遵循 .mailmap,参见 git-shortlog[1] 或 git-blame[1])
- %ge
-
引用日志身份电子邮件
- %gE
-
引用日志身份电子邮件(遵循 .mailmap,参见 git-shortlog[1] 或 git-blame[1])
- %gs
-
引用日志主题
- %(trailers[:<options>])
-
显示 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> 具有相同的语义。
-
-
注意
|
某些占位符可能取决于修订版本遍历引擎给出的其他选项。例如,除非我们正在遍历引用日志条目(例如,通过 git log -g ),否则 %g* 引用日志选项将插入一个空字符串。如果命令行上尚未提供 --decorate ,则 %d 和 %D 占位符将使用“短”装饰格式。 |
布尔选项接受可选值 [=
<bool-value>]。git-config[1] 的 --type=bool
接受的值,如 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
log
不生成任何差异输出。以下选项可用于显示每个提交所做的更改。
请注意,除非明确给出 --diff-merges
变体之一(包括短选项 -m
、-c
、--cc
和 --dd
),否则合并提交不会显示差异,即使选择了像 --patch
这样的差异格式,也不会匹配像 -S
这样的搜索选项。例外情况是使用 --first-parent
时,在这种情况下,first-parent
是合并提交的默认格式。
-p
-u
--patch
-
生成补丁(参见 使用 -p 生成补丁文本)。
-s
--no-patch
-
抑制差异机制的所有输出。对于像
git
show
这样默认显示补丁的命令,它可用于抑制其输出,或在别名中取消命令行上早期选项(如--patch
、--stat
)的效果。 - -m
-
以默认格式显示合并提交的差异。这类似于
--diff-merges=on
,不同之处在于,除非同时给出-p
,否则-m
不会产生任何输出。 - -c
-
为合并提交生成组合差异输出。是
--diff-merges=combined
-p
的快捷方式。 - --cc
-
为合并提交生成紧凑组合差异输出。是
--diff-merges=dense-combined
-p
的快捷方式。 - --dd
-
对于合并提交和常规提交,生成相对于第一个父提交的差异。是
--diff-merges=first-parent
-p
的快捷方式。 - --remerge-diff
-
为合并提交生成重新合并差异输出。是
--diff-merges=remerge
-p
的快捷方式。 - --no-diff-merges
-
是
--diff-merges=off
的同义词。 - --diff-merges=<format>
-
指定用于合并提交的差异格式。除非使用
--first-parent
,否则默认为 `off`,在这种情况下,first-parent
是默认值。支持以下格式:
- off, none
-
禁用合并提交的差异输出。用于覆盖隐含值。
- on, m
-
使合并提交的差异输出以默认格式显示。默认格式可以通过
log.diffMerges
配置变量更改,其默认值为separate
。 - first-parent, 1
-
显示相对于第一个父提交的完整差异。这与
--patch
为非合并提交生成的格式相同。 - separate
-
显示相对于每个父提交的完整差异。为每个父提交生成单独的日志条目和差异。
- combined, c
-
同时显示每个父提交与合并结果之间的差异,而不是一次显示一个父提交与结果之间的成对差异。此外,它只列出从所有父提交中修改过的文件。
- dense-combined, cc
-
通过省略不重要的代码块进一步压缩
--diff-merges=combined
生成的输出,这些代码块在父提交中的内容只有两种变体,并且合并结果未经修改地选择了其中一种。 - remerge, r
-
重新合并两个父提交的合并提交以创建临时树对象——可能包含带有冲突标记等的文件。然后显示该临时树与实际合并提交之间的差异。
使用此选项时发出的输出可能会更改,并且它与其他选项的交互也会更改(除非有明确文档说明)。
- --combined-all-paths
-
使组合差异(用于合并提交)列出所有父提交的文件名。因此,它仅在
--diff-merges=
[dense-
]combined
使用时生效,并且可能仅在检测到文件名更改时有用(即在请求了重命名或复制检测时)。 -U
<n>--unified=
<n>-
生成包含 <n> 行上下文(而不是通常的三行)的 diff。隐含
--patch
。 --output=
<file>-
输出到特定文件而不是标准输出。
--output-indicator-new=
<char>--output-indicator-old=
<char>--output-indicator-context=
<char>-
指定用于指示生成补丁中新行、旧行或上下文行的字符。通常它们分别是
+
、-
和 ' '。 --raw
-
对于每个提交,使用原始差异格式显示更改摘要。参见 git-diff[1] 的“原始输出格式”部分。这与以原始格式显示日志本身不同,后者可以通过
--format=raw
实现。 --patch-with-raw
-
-p
--raw
的同义词。 -t
-
在差异输出中显示树对象。
--indent-heuristic
-
启用启发式算法,该算法会移动差异块边界,使补丁更易于阅读。这是默认设置。
--no-indent-heuristic
-
禁用缩进启发式算法。
--minimal
-
花费额外时间以确保生成最小的差异。
--patience
-
使用“patience diff”算法生成差异。
--histogram
-
使用“histogram diff”算法生成差异。
--anchored=
<text>-
使用“anchored diff”算法生成差异。
此选项可以多次指定。
如果一行在源和目标中都存在,只存在一次,并且以 <text> 开头,则此算法会尝试阻止其在输出中显示为删除或添加。它内部使用“patience diff”算法。
--diff-algorithm=
(patience
|minimal
|histogram
|myers
)-
选择一种差异算法。变体如下:
例如,如果您将
diff.algorithm
变量配置为非默认值,但希望使用默认值,则必须使用--diff-algorithm=default
选项。 --stat
[=
<width>[,
<name-width>[,
<count>]]]-
生成差异统计(diffstat)。默认情况下,文件名部分将使用尽可能多的空间,其余部分用于图形部分。最大宽度默认为终端宽度,如果未连接到终端则为 80 列,可以通过 <width> 覆盖。文件名部分的宽度可以通过在逗号后给出另一个宽度 <name-width> 或设置
diff.statNameWidth=
<name-width> 来限制。图形部分的宽度可以通过使用--stat-graph-width=
<graph-width> 或设置diff.statGraphWidth=
<graph-width> 来限制。使用--stat
或--stat-graph-width
会影响所有生成统计图的命令,而设置diff.statNameWidth
或diff.statGraphWidth
不会影响git
format-patch
。通过给出第三个参数 <count>,您可以将输出限制为前 <count> 行,如果还有更多,则后面跟 ...。这些参数也可以通过
--stat-width=
<width>、--stat-name-width=
<name-width> 和--stat-count=
<count> 单独设置。 --compact-summary
-
在差异统计中输出扩展头信息的精简摘要,例如文件创建或删除(“new”或“gone”,可选
+l
如果是符号链接)和模式更改(添加或移除可执行位的+x
或-x
)。这些信息放置在文件名部分和图形部分之间。暗示--stat
。 --numstat
-
类似于
--stat
,但显示添加和删除的行数以十进制表示,并且路径名不缩写,使其更具机器友好性。对于二进制文件,输出两个-
而不是显示0
0
。 --shortstat
-
仅输出
--stat
格式的最后一行,其中包含修改文件的总数,以及添加和删除的行数。 -X
[<param>,...
]--dirstat
[=
<param>,...
]-
输出每个子目录的相对改动量分布。
--dirstat
的行为可以通过传递逗号分隔的参数列表进行自定义。默认值由diff.dirstat
配置变量控制(参见 git-config[1])。以下参数可用:changes
-
通过计算已从源中删除或已添加到目标中的行数来计算目录统计数字。这会忽略文件内纯代码移动的数量。换句话说,文件内行的重新排列不会像其他更改那样被大量计数。这是未给出参数时的默认行为。
lines
-
通过执行常规的基于行的差异分析并汇总删除/添加的行数来计算目录统计数字。(对于二进制文件,而是计算 64 字节块,因为二进制文件没有自然的行概念)。这比
changes
行为更昂贵,但它会将文件内重新排列的行与其他更改一样进行计数。结果输出与您从其他--*stat
选项获得的输出一致。 files
-
通过计算更改的文件数量来计算目录统计数字。在目录统计分析中,每个更改的文件都同等计数。这是计算成本最低的
--dirstat
行为,因为它根本不需要查看文件内容。 cumulative
-
也计算子目录中更改对父目录的影响。请注意,使用
cumulative
时,报告的百分比总和可能超过 100%。默认(非累积)行为可以通过noncumulative
参数指定。 - <limit>
-
一个整数参数,指定一个截止百分比(默认为 3%)。对更改贡献低于此百分比的目录不会显示在输出中。
示例:例如,以下命令将统计更改的文件,同时忽略更改文件总量少于10%的目录,并将子目录的计数累加到父目录中:
--dirstat=files,10,cumulative
。 --cumulative
-
--dirstat=cumulative
的同义词。 --dirstat-by-file
[=
<param>,...
]-
--dirstat=files,
<param>,...
的同义词。 --summary
-
输出扩展头信息的精简摘要,例如创建、重命名和模式更改。
--patch-with-stat
-
-p
--stat
的同义词。 -z
-
使用NUL字符而非换行符来分隔提交。
此外,当
--raw
或--numstat
给定后,不要混淆路径名,并使用NUL字符作为输出字段终止符。如果没有此选项,包含“不寻常”字符的路径名将按照配置变量
core.quotePath
的解释进行引用(参见 git-config[1])。 --name-only
-
仅显示后像树中每个已更改文件的名称。文件名通常以 UTF-8 编码。有关更多信息,请参阅 git-log[1] 手册页中关于编码的讨论。
--name-status
-
只显示每个更改文件的名称和状态。有关状态字母的含义,请参阅
--diff-filter
选项的说明。与--name-only
类似,文件名通常以UTF-8编码。 --submodule
[=
<format>]-
指定如何显示子模块的差异。当指定
--submodule=short
时,使用short
格式。此格式仅显示范围内提交的起始和结束名称。当指定--submodule
或--submodule=log
时,使用log
格式。此格式列出范围内的提交,就像git-submodule[1]的summary
一样。当指定--submodule=diff
时,使用diff
格式。此格式显示提交范围内子模块内容的行内差异。如果未设置配置选项,则默认为diff.submodule
或short
格式。 --color
[=
<when>]-
显示彩色差异。
--color
(即不带=
<when>时)等同于--color=always
。<when>可以是always
、never
或auto
之一。 --no-color
-
关闭彩色 diff。它与
--color=never
相同。 --color-moved
[=
<mode>]-
移动的代码行会以不同颜色显示。如果未指定选项,<mode>默认为
no
;如果给定不带模式的选项,则默认为zebra
。模式必须是以下之一:no
-
移动的行不进行高亮显示。
default
-
是
zebra
的同义词。未来可能会更改为更合理的模式。 plain
-
在某个位置添加又在另一个位置删除的任何行将使用
color.diff.newMoved
颜色显示。类似地,color.diff.oldMoved
将用于差异中在其他位置添加的已删除行。此模式会捕获任何移动的行,但在审查时,若要确定代码块是否未经过置换而移动,则此模式用处不大。 blocks
-
至少20个字母数字字符的移动文本块会被贪婪地检测到。检测到的块将使用
color.diff.
(old
|new
)Moved
颜色进行着色。相邻的块无法区分。 zebra
-
移动文本块的检测方式与
blocks
模式相同。这些块将使用color.diff.
(old
|new
)Moved
颜色或color.diff.
(old
|new
)MovedAlternative
颜色进行着色。两种颜色之间的变化表示检测到了新的块。 dimmed-zebra
-
与
zebra
类似,但会对移动代码中不重要的部分进行额外变暗处理。两个相邻块的边界行被视为重要,其余则不重要。dimmed_zebra
是一个已弃用的同义词。
--no-color-moved
-
关闭移动检测。这可以用于覆盖配置设置。它与
--color-moved=no
相同。 --color-moved-ws=
<mode>,...
-
这配置了在执行
--color-moved
的移动检测时如何忽略空白。这些模式可以作为逗号分隔的列表给出: --no-color-moved-ws
-
执行移动检测时不忽略空白。这可以用于覆盖配置设置。它与
--color-moved-ws=no
相同。 --word-diff
[=
<mode>]-
默认情况下,单词由空白分隔;参见下面的
--word-diff-regex
。<mode> 默认为plain
,并且必须是以下之一:请注意,尽管第一个模式的名称如此,如果启用,所有模式都使用颜色高亮显示更改的部分。
--word-diff-regex=
<regex>-
使用 <regex> 来决定什么是单词,而不是将非空白字符的连续序列视为一个单词。除非已启用,否则这也隐含
--word-diff
。<regex>的每个不重叠匹配都被视为一个单词。这些匹配之间的任何内容都被视为空白并被忽略(!)以查找差异。您可能希望在正则表达式中附加|[
^
[:space:
]]以确保它匹配所有非空白字符。包含换行符的匹配会在换行符处被静默截断(!)例如,
--word-diff-regex=.
会将每个字符视为一个单词,并相应地逐字符显示差异。正则表达式也可以通过差异驱动程序或配置选项设置,请参阅gitattributes[5]或git-config[1]。显式指定它会覆盖任何差异驱动程序或配置设置。差异驱动程序会覆盖配置设置。
--color-words
[=
<regex>]-
相当于
--word-diff=color
加上(如果指定了正则表达式)--word-diff-regex=
<regex>。 --no-renames
-
关闭重命名检测,即使配置文件默认开启。
--
[no-
]rename-empty
-
是否使用空 blob 作为重命名源。
--check
-
如果更改引入了冲突标记或空白错误,则发出警告。哪些被认为是空白错误由
core.whitespace
配置控制。默认情况下,行尾空白(包括仅由空白组成的行)以及行初始缩进内紧跟制表符的空格字符都被视为空白错误。如果发现问题,则以非零状态退出。与--exit-code
不兼容。 --ws-error-highlight=
<kind>-
高亮显示差异的
context
、old
或new
行中的空白错误。多个值用逗号分隔,none
会重置先前的值,default
会将列表重置为new
,all
是old,new,context
的简写。如果未给定此选项且未设置配置变量diff.wsErrorHighlight
,则仅高亮显示new
行中的空白错误。空白错误会使用color.diff.whitespace
着色。 --full-index
-
在生成补丁格式输出时,不在“index”行上显示前几个字符,而是显示完整的原图像和后图像 blob 对象名称。
--binary
-
除了
--full-index
之外,还输出一个二进制 diff,该 diff 可以用git-apply
应用。隐含--patch
。 --abbrev
[=
<n>]-
在diff-raw格式输出和diff-tree头行中,不显示完整的40字节十六进制对象名称,而是显示最短的、至少<n>位十六进制数字的唯一标识对象的短前缀。在diff-patch输出格式中,
--full-index
具有更高的优先级,即如果指定了--full-index
,则无论--abbrev
如何,都将显示完整的blob名称。非默认的位数可以通过--abbrev=
<n>指定。 -B
[<n>][/
<m>]--break-rewrites
[=
[<n>][/
<m>]]-
将完整的重写更改分解为删除和创建对。这有两个目的:
它影响文件完全重写时的变更显示方式:不显示为一连串删除和插入(其中只有极少数行与上下文文本匹配),而是显示为一次性删除所有旧内容,然后一次性插入所有新内容,数字<m>控制
-B
选项的这一方面(默认为60%)。-B/70%
指定,如果结果中保留的原始内容少于30%,Git会将其视为完全重写(即,否则生成的补丁将是一系列删除和插入与上下文行混合在一起)。当与
-M
一起使用时,完全重写的文件也被视为重命名的源(通常-M
只将已消失的文件视为重命名的源),数字<n>控制-B
选项的这一方面(默认为50%)。-B20%
指定,与文件大小的20%或更多进行增删的更改,有资格被视为重命名到另一个文件的可能来源。 -M
[<n>]--find-renames
[=
<n>]-
如果生成差异,则为每个提交检测并报告重命名。有关遍历历史记录时跨重命名跟踪文件的信息,请参阅
--follow
。如果<n>是指定的,它是相似性指数的阈值(即与文件大小相比的添加/删除量)。例如,-M90%
表示如果文件有90%以上未更改,Git应将删除/添加对视为重命名。不带%
符号时,该数字应理解为小数,小数点位于数字之前。例如,-M5
变为0.5,因此与-M50%
相同。类似地,-M05
与-M5%
相同。若要将检测限制为精确重命名,请使用-M100%
。默认相似性指数为50%。 -C
[<n>]--find-copies
[=
<n>]-
检测复制和重命名。另请参见
--find-copies-harder
。如果指定了 <n>,其含义与-M
<n> 相同。 --find-copies-harder
-
出于性能原因,默认情况下,
-C
选项仅在复制的原始文件在同一变更集中被修改时才查找副本。此标志使命令检查未修改的文件作为复制源的候选文件。这对于大型项目来说是一个非常昂贵的操作,因此请谨慎使用。给定多个-C
选项具有相同的效果。 -D
--irreversible-delete
-
删除时省略原始图像(preimage),即只打印头信息,而不打印原始图像与
/dev/null
之间的差异。生成的补丁不适用于patch
或git
apply
;这仅适用于那些只想专注于审查更改后文本的人。此外,输出显然缺乏足够的信息来逆向应用此类补丁,即使是手动操作也不行,因此得名此选项。与
-B
一起使用时,也会省略删除/创建对的删除部分中的原始图像。 -l
<num>-
-M
和-C
选项包含一些初步步骤,可以廉价地检测重命名/复制的子集,然后是穷举回退部分,将所有剩余的未配对目标与所有相关源进行比较。(对于重命名,只有剩余的未配对源是相关的;对于复制,所有原始源都是相关的。)对于N个源和目标,这种穷举检查的时间复杂度为O(N^2)。如果涉及的源/目标文件数量超过指定值,此选项可阻止重命名/复制检测的穷举部分运行。默认为diff.renameLimit
。请注意,值0被视为无限制。 --diff-filter=
[(A
|C
|D
|M
|R
|T
|U
|X
|B
)...
[*
]]-
只选择那些已添加(
A
)、已复制(C
)、已删除(D
)、已修改(M
)、已重命名(R
)、类型(即普通文件、符号链接、子模块等)已更改(T
)、未合并(U
)、未知(X
)或配对已损坏(B
)的文件。可以使用过滤字符的任意组合(包括不使用任何字符)。当*
(全选或不选)添加到组合中时,如果比较中有任何文件匹配其他条件,则选择所有路径;如果没有文件匹配其他条件,则不选择任何内容。此外,这些大写字母可以小写以进行排除。例如,
--diff-filter=ad
会排除已添加和已删除的路径。请注意,并非所有 diff 都能包含所有类型。例如,如果禁用对这些类型的检测,则不会出现已复制和已重命名条目。
-S
<string>-
查找更改文件中指定 <string> 出现次数(即添加/删除)的差异。供脚本编写者使用。
当您正在寻找一个精确的代码块(如结构体)并希望了解该代码块自首次出现以来的历史记录时,它非常有用:迭代使用此功能,将原始图像中感兴趣的代码块重新输入到
-S
中,并持续操作直到找到该代码块的最初版本。二进制文件也会被搜索。
-G
<regex>-
查找其补丁文本包含与 <regex> 匹配的添加/删除行的差异。
为了说明
-S
<regex>--pickaxe-regex
和-G
<regex>之间的区别,请考虑同一个文件中包含以下差异的提交+ return frotz(nitfol, two->ptr, 1, 0); ... - hit = frotz(nitfol, mf2.ptr, 1, 0);
虽然git log -G"frotz\(nitfol"会显示此提交,但git log -S"frotz\(nitfol" --pickaxe-regex不会(因为该字符串的出现次数没有变化)。
除非提供了
--text
,否则没有 textconv 过滤器的二进制文件的补丁将被忽略。有关更多信息,请参见 gitdiffcore[7] 中的 *pickaxe* 条目。
--find-object=
<object-id>-
查找更改指定对象出现次数的差异。类似于
-S
,只是参数不同,它不搜索特定字符串,而是搜索特定对象 ID。该对象可以是 blob 或子模块提交。它隐含了
git-log
中的-t
选项,以也查找树。 --pickaxe-all
-
当
-S
或-G
找到更改时,显示该变更集中所有更改,而不仅仅是包含 <string> 更改的文件。 --pickaxe-regex
-
将提供给
-S
的 <string> 视为扩展的 POSIX 正则表达式进行匹配。 -O
<orderfile>-
控制文件在输出中出现的顺序。这会覆盖
diff.orderFile
配置变量(参见git-config[1])。要取消diff.orderFile
,请使用-O/dev/null
。输出顺序由<orderfile>中的glob模式顺序决定。所有路径名匹配第一个模式的文件首先输出,所有路径名匹配第二个模式(但不匹配第一个)的文件其次输出,依此类推。所有路径名不匹配任何模式的文件最后输出,就像文件末尾有一个隐式匹配所有模式一样。如果多个路径名具有相同的级别(它们匹配相同的模式但没有匹配更早的模式),则它们相对于彼此的输出顺序是正常顺序。
<orderfile> 解析如下:
-
空行被忽略,因此它们可以用作分隔符以提高可读性。
-
以井号("
#
")开头的行被忽略,因此它们可以用作注释。如果模式以井号开头,请在模式开头添加反斜杠("\")。 -
其他每行包含一个模式。
模式具有与
fnmatch
(3)中使用的模式相同的语法和语义,但不带FNM_PATHNAME
标志,例外是如果删除最终路径名的任意数量的组件后匹配模式,则路径名也会匹配该模式。例如,模式"foo*bar
"匹配"fooasdfbar
"和"foo/bar/baz/asdf
"但不匹配"foobarx
"。 -
--skip-to=
<file>--rotate-to=
<file>-
从输出中丢弃在命名文件<file>之前的文件(即跳过到),或将其移动到输出末尾(即旋转到)。这些选项主要为
git
difftool
命令而设计,否则可能用处不大。 -R
-
交换两个输入;即,显示从索引或磁盘文件到树内容的差异。
--relative
[=
<path>]--no-relative
-
在项目子目录中运行时,可以使用此选项排除目录外的更改并显示相对于该目录的路径名。当您不在子目录中(例如在裸仓库中)时,可以通过提供<path>作为参数来指定输出相对于哪个子目录。
--no-relative
可用于撤销diff.relative
配置选项和先前的--relative
。 -a
--text
-
将所有文件视为文本。
--ignore-cr-at-eol
-
进行比较时忽略行尾的回车符。
--ignore-space-at-eol
-
忽略行尾空格的更改。
-b
--ignore-space-change
-
忽略空格数量的变化。这会忽略行尾的空格,并将所有其他一个或多个空格序列视为等效。
-w
--ignore-all-space
-
比较行时忽略空格。即使一行有空格而另一行没有,这也忽略了差异。
--ignore-blank-lines
-
忽略所有空行的更改。
-I
<regex>--ignore-matching-lines=
<regex>-
忽略所有行都匹配 <regex> 的更改。此选项可以多次指定。
--inter-hunk-context=
<number>-
在差异块之间显示上下文,最多达指定行数 <number>,从而合并彼此接近的块。默认为
diff.interHunkContext
,如果未设置配置选项则为 0。 -W
--function-context
-
为每个更改显示整个函数作为上下文行。函数名称的确定方式与
git
diff
确定补丁块头(patch hunk headers)的方式相同(请参阅gitattributes[5]中的“定义自定义块头”)。 --ext-diff
-
允许执行外部差异辅助程序。如果您使用 gitattributes[5] 设置了外部差异驱动程序,则需要与 git-log[1] 等命令一起使用此选项。
--no-ext-diff
-
禁止外部差异驱动程序。
--textconv
--no-textconv
-
允许(或不允许)在比较二进制文件时运行外部文本转换过滤器。有关详细信息,请参阅gitattributes[5]。由于文本转换过滤器通常是单向转换,因此生成的差异适合人工阅读,但无法应用。因此,文本转换过滤器默认只对git-diff[1]和git-log[1]启用,而不对git-format-patch[1]或diff底层命令启用。
--ignore-submodules
[=
(none
|untracked
|dirty
|all
)]-
在生成差异时忽略对子模块的更改。
all
是默认值。使用none
会在子模块包含未跟踪或已修改文件,或者其HEAD
与超级项目中记录的提交不同时,将其视为已修改,并且可以覆盖git-config[1]或gitmodules[5]中ignore
选项的任何设置。使用untracked
时,如果子模块只包含未跟踪内容,则不将其视为脏(但仍会扫描已修改内容)。使用dirty
会忽略对子模块工作树的所有更改,仅显示超级项目中所存储提交的更改(这是1.7.0之前的行为)。使用all
会隐藏对子模块的所有更改。 --src-prefix=
<prefix>-
显示给定的源前缀 <prefix> 而不是 "a/"。
--dst-prefix=
<prefix>-
显示给定的目标前缀 <prefix> 而不是 "b/"。
--no-prefix
-
不显示任何源或目标前缀。
--default-prefix
-
使用默认的源和目标前缀("a/"和"b/")。这会覆盖配置变量,例如
diff.noprefix
、diff.srcPrefix
、diff.dstPrefix
和diff.mnemonicPrefix
(参见git-config[1])。 --line-prefix=
<prefix>-
在每行输出前面添加一个额外的 <prefix>。
--ita-invisible-in-index
-
默认情况下,通过
git
add
-N
添加的条目在git
diff
中显示为已存在的空文件,在git
diff
--cached
中显示为新文件。此选项使该条目在git
diff
中显示为新文件,在git
diff
--cached
中显示为不存在。此选项可以通过--ita-visible-in-index
恢复。这两个选项都是实验性的,将来可能会被移除。
有关这些通用选项的更详细说明,另请参见 gitdiffcore[7]。
使用 -p 生成补丁文本
使用-p
选项运行git-diff[1]、git-log[1]、git-show[1]、git-diff-index[1]、git-diff-tree[1]或git-diff-files[1]会生成补丁文本。您可以通过GIT_EXTERNAL_DIFF
和GIT_DIFF_OPTS
环境变量(参见git[1])以及diff
属性(参见gitattributes[5])自定义补丁文本的创建。
-p
选项生成的输出与传统的 diff 格式略有不同:
-
它前面是“git diff”头,看起来像这样:
diff --git a/file1 b/file2
除非涉及重命名/复制,否则
a/
和b/
文件名是相同的。特别是,即使是创建或删除,也不会使用/dev/null
代替a/
或b/
文件名。当涉及重命名/复制时,
file1
和file2
分别显示重命名/复制的源文件名称和重命名/复制生成的文件名称。 -
后面跟着一个或多个扩展头行:
old
mode
<mode>new
mode
<mode>deleted
file
mode
<mode>new
file
mode
<mode>copy
from
<path>copy
to
<path>rename
from
<path>rename
to
<path>similarity
index
<number>dissimilarity
index
<number>index
<hash>..
<hash> <mode>文件模式 <mode> 以 6 位八进制数字打印,包括文件类型和文件权限位。
扩展头中的路径名不包含
a/
和b/
前缀。相似性指数是未更改行的百分比,而相异性指数是已更改行的百分比。它是一个向下取整的整数,后面跟着一个百分号。因此,相似性指数100%的值保留给两个相同的文件,而100%的相异性意味着旧文件中没有一行进入新文件。
索引行包括更改前后的 blob 对象名称。如果文件模式没有更改,则包含 <mode>;否则,单独的行指示旧模式和新模式。
-
包含“不寻常”字符的路径名将按照配置变量
core.quotePath
的解释进行引用(参见 git-config[1])。 -
输出中所有的
file1
文件指代提交前的文件,而所有的file2
文件指代提交后的文件。按顺序将每个更改应用到每个文件是错误的。例如,这个补丁将交换a和bdiff --git a/a b/b rename from a rename to b diff --git a/b b/a rename from b rename to a
-
Hunk 头会提及 hunk 应用到的函数名称。有关如何根据特定语言进行调整的详细信息,请参见 gitattributes[5] 中的“定义自定义 hunk-header”。
组合 diff 格式
任何生成差异的命令都可以接受-c
或--cc
选项,以便在显示合并时生成合并差异。这是使用git-diff[1]或git-show[1]显示合并时的默认格式。另请注意,您可以为这些命令中的任何一个提供适当的--diff-merges
选项,以强制生成特定格式的差异。
“组合 diff”格式如下所示:
diff --combined describe.c index fabadb8,cc95eb0..4866510 --- a/describe.c +++ b/describe.c @@@ -98,20 -98,12 +98,20 @@@ return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1; } - static void describe(char *arg) -static void describe(struct commit *cmit, int last_one) ++static void describe(char *arg, int last_one) { + unsigned char sha1[20]; + struct commit *cmit; struct commit_list *list; static int initialized = 0; struct commit_name *n; + if (get_sha1(arg, sha1) < 0) + usage(describe_usage); + cmit = lookup_commit_reference(sha1); + if (!cmit) + usage(describe_usage); + if (!initialized) { initialized = 1; for_each_ref(get_name);
-
它前面是“git diff”头,看起来像这样(使用
-c
选项时):diff --combined file
或者像这样(使用
--cc
选项时):diff --cc file
-
后面跟着一个或多个扩展头行(此示例显示了一个包含两个父级的合并):
index
<hash>,
<hash>..
<hash>mode
<mode>,
<mode>..
<mode>new
file
mode
<mode>deleted
file
mode
<mode>,
<mode>mode
<mode>,
<mode>..
<mode>行仅在至少一个<mode>与其他模式不同时出现。包含检测到的内容移动(重命名和复制检测)信息的扩展头旨在与两个<tree-ish>的差异配合使用,并且不用于合并差异格式。 -
后面跟着一个两行的“源文件/目标文件”头:
--- a/file +++ b/file
类似于传统 unified diff 格式的两行头,
/dev/null
用于指示已创建或已删除的文件。然而,如果提供了 --combined-all-paths 选项,您将得到一个 N+1 行的“源文件/目标文件”头,而不是两行的“源文件/目标文件”头,其中 N 是合并提交中父级的数量:
--- a/file --- a/file --- a/file +++ b/file
如果重命名或复制检测处于活动状态,这种扩展格式会很有用,可以让您查看不同父级中文件的原始名称。
-
块头格式已修改,以防止人们意外将其提供给
patch
-p1
。合并差异格式是为审查合并提交更改而创建的,并非用于应用。此更改类似于扩展索引头中的更改@@@ <from-file-range> <from-file-range> <to-file-range> @@@
组合 diff 格式的块头中有(父级数量 + 1)个
@
字符。
与传统的统一差异格式不同,传统格式显示两个文件A和B,带有一个单列前缀,其中-
表示(减号 — 出现在A中但在B中被删除),+
表示(加号 — 在A中缺失但在B中添加),或者"
"
表示(空格 — 未更改);此格式将两个或多个文件 file1、file2 等与一个文件 X 进行比较,并显示 X 与每个 fileN 的差异。输出行前会为每个fileN添加一个列,以表示X的行与它的差异。
列N中的-
字符表示该行出现在fileN中,但未出现在结果中。列N中的+
字符表示该行出现在结果中,而fileN没有该行(换句话说,从该父级的角度来看,该行是添加的)。
在上述示例输出中,函数签名从两个文件都发生了更改(因此 file1 和 file2 中都有两个-
被删除,加上++
表示添加的一行未出现在 file1 或 file2 中)。此外,其他八行与 file1 相同,但未出现在 file2 中(因此以+
为前缀)。
当由 git
diff-tree
-c
显示时,它会将合并提交的父节点与合并结果进行比较(即 file1..fileN 是父节点)。当由 git
diff-files
-c
显示时,它会将两个未解决的合并父节点与工作区文件进行比较(即 file1 是阶段 2,也称为“我们的版本”;file2 是阶段 3,也称为“他们的版本”)。
示例
git
log
--no-merges
-
显示完整的提交历史,但跳过任何合并。
git
log
v2.6.12..
include/scsi
drivers/scsi
-
显示从版本 v2.6.12 开始,更改了
include/scsi
或drivers/scsi
子目录中任何文件的所有提交。 git
log
--since="2
weeks
ago"
--
gitk
-
显示过去两周内对文件 gitk 的更改。使用
--
是为了避免与名为 gitk 的 **分支** 混淆。 git
log
--name-status
release..test
-
显示在“test”分支中但尚未在“release”分支中的提交,以及每个提交修改的路径列表。
git
log
--follow
builtin/rev-list.c
-
显示更改了
builtin/rev-list.c
的提交,包括在该文件被赋予当前名称之前发生的提交。 git
log
--branches
--not
--remotes=origin
-
显示存在于任何本地分支中但不存在于 origin 的任何远程跟踪分支中的所有提交(即你拥有而 origin 没有的)。
git
log
master
--not
--remotes=*/master
-
显示存在于本地 master 分支中但不存在于任何远程仓库的 master 分支中的所有提交。
git
log
-p
-m
--first-parent
-
显示历史记录,包括更改差异,但仅从“主分支”的角度,跳过来自已合并分支的提交,并显示由合并引入的更改的完整差异。这仅在遵循严格策略,即在保持单个集成分支时合并所有主题分支时才有意义。
git
log
-L
/int
main/',/^}/:main.c
-
显示文件
main.c
中函数main
() 如何随时间演变。 git
log
-3
-
将要显示的提交数量限制为 3。
讨论
Git 在某种程度上是字符编码无关的。
-
blob 对象的内容是未经解释的字节序列。核心层面没有编码转换。
-
路径名采用 UTF-8 C 规范化形式编码。这适用于树对象、索引文件、引用名称,以及命令行参数、环境变量和配置文件(
.git/config
(参见 git-config[1])、gitignore[5]、gitattributes[5] 和 gitmodules[5])中的路径名。请注意,Git 在核心层面将路径名简单地视为非 NUL 字节序列,没有路径名编码转换(Mac 和 Windows 除外)。因此,即使在使用传统扩展 ASCII 编码的平台和文件系统上,使用非 ASCII 路径名也大多可以正常工作。但是,在此类系统上创建的仓库在基于 UTF-8 的系统(例如 Linux、Mac、Windows)上将无法正常工作,反之亦然。此外,许多基于 Git 的工具简单地假定路径名为 UTF-8,并且无法正确显示其他编码。
-
提交日志消息通常以 UTF-8 编码,但也支持其他扩展 ASCII 编码。这包括 ISO-8859-x、CP125x 以及许多其他编码,但 *不* 包括 UTF-16/32、EBCDIC 和 CJK 多字节编码(GBK、Shift-JIS、Big5、EUC-x、CP9xx 等)。
尽管我们鼓励提交日志消息使用 UTF-8 编码,但核心 Git 和 Git Porcelain 都设计为不强制项目使用 UTF-8。如果某个项目的所有参与者觉得使用传统编码更方便,Git 并不会禁止。但是,有几点需要记住。
-
git
commit
和git
commit-tree
会发出警告,如果提交日志消息看起来不像有效的 UTF-8 字符串,除非您明确指出您的项目使用传统编码。表示此意的方式是在.git/config
文件中设置i18n.commitEncoding
,如下所示[i18n] commitEncoding = ISO-8859-1
使用上述设置创建的提交对象会在其
encoding
头中记录i18n.commitEncoding
的值。这有助于以后查看它们的人。缺少此头则意味着提交日志消息以 UTF-8 编码。 -
git
log
、git
show
、git
blame
等命令会查看提交对象的encoding
头,并尝试将日志消息重新编码为 UTF-8,除非另有指定。您可以通过在.git/config
文件中设置i18n.logOutputEncoding
来指定所需的输出编码,如下所示[i18n] logOutputEncoding = ISO-8859-1
如果您没有此配置变量,则会使用
i18n.commitEncoding
的值。
请注意,我们故意选择在提交时不对提交日志消息进行重新编码以强制在提交对象级别使用 UTF-8,因为重新编码为 UTF-8 不一定是可逆操作。
配置
有关核心变量,请参阅 git-config[1];有关差异生成设置,请参阅 git-diff[1]。
本节中此行以上的所有内容均未包含在 git-config[1] 文档中。以下内容与该文档中的内容相同
- log.abbrevCommit
-
如果为 true,则使 git-log[1]、git-show[1] 和 git-whatchanged[1] 假定使用
--abbrev-commit
选项。您可以使用--no-abbrev-commit
选项覆盖此设置。 - log.date
-
设置 log 命令的默认日期时间模式。为 log.date 设置值类似于使用 git log 的
--date
选项。详见 git-log[1]。如果格式设置为 "auto:foo" 且正在使用分页器,则日期格式将使用 "foo" 格式。否则,将使用 "default"。
- log.decorate
-
打印出 log 命令显示的任何提交的引用名称。如果指定了 short,则不会打印引用名称前缀 refs/heads/、refs/tags/ 和 refs/remotes/。如果指定了 full,则会打印完整的引用名称(包括前缀)。如果指定了 auto,那么如果输出到终端,引用名称将以 short 模式显示,否则不显示引用名称。这与
git
log
命令的--decorate
选项相同。 - log.initialDecorationSet
-
默认情况下,
git
log
仅显示某些已知引用命名空间的装饰。如果指定了 all,则显示所有引用作为装饰。 - log.excludeDecoration
-
从日志装饰中排除指定的模式。这类似于
--decorate-refs-exclude
命令行选项,但此配置选项可被--decorate-refs
选项覆盖。 - log.diffMerges
-
设置当指定
--diff-merges=on
时使用的差异格式,详见 git-log[1] 中的--diff-merges
选项。默认为separate
。 - log.follow
-
如果为
true
,则当给定单个 <path> 时,git
log
将表现得如同使用了--follow
选项。这与--follow
具有相同的限制,即它不能用于跟踪多个文件,并且在非线性历史记录上效果不佳。 - log.graphColors
-
一个以逗号分隔的颜色列表,可用于在
git
log
--graph
中绘制历史线条。 - log.showRoot
-
如果为 true,则初始提交将显示为一个大型创建事件。这相当于与一个空树进行差异比较。像 git-log[1] 或 git-whatchanged[1] 这样通常会隐藏根提交的工具现在将显示它。默认为 true。
- log.showSignature
-
如果为 true,则使 git-log[1]、git-show[1] 和 git-whatchanged[1] 假定使用
--show-signature
选项。 - log.mailmap
-
如果为 true,则使 git-log[1]、git-show[1] 和 git-whatchanged[1] 假定使用
--use-mailmap
选项,否则假定使用--no-use-mailmap
选项。默认为 true。 notes.mergeStrategy
-
解决备注冲突时默认选择的合并策略。必须是
manual
、ours
、theirs
、union
或cat_sort_uniq
之一。默认为manual
。有关每种策略的更多信息,请参阅 git-notes[1] 的“NOTES MERGE STRATEGIES”部分。此设置可以通过向 git-notes[1] 传递
--strategy
选项来覆盖。 notes.
<name>.mergeStrategy
-
将备注合并到
refs/notes/
<name> 时选择的合并策略。这会覆盖更通用的notes.mergeStrategy
设置。有关可用策略的更多信息,请参阅 git-notes[1] 的“NOTES MERGE STRATEGIES”部分。 notes.displayRef
-
在显示提交消息时,除了由
core.notesRef
或GIT_NOTES_REF
设置的默认引用外,还从哪个引用(或多个引用,如果是 glob 模式或多次指定)读取备注,在使用git
log
系列命令时。此设置可以通过
GIT_NOTES_DISPLAY_REF
环境变量覆盖,该变量必须是一个以冒号分隔的引用或 glob 列表。对于不存在的引用将发出警告,但与任何引用不匹配的 glob 将被静默忽略。
此设置可通过 git-log[1] 系列命令的
--no-notes
选项禁用,或通过这些命令接受的--notes=
<ref> 选项禁用。core.notesRef
的有效值(可能被GIT_NOTES_REF
覆盖)也会隐式添加到要显示的引用列表中。 notes.rewrite.
<command>-
当使用 <command>(当前为
amend
或rebase
)重写提交时,如果此变量为false
,git 将不会从原始提交复制备注到重写后的提交。默认为true
。另请参阅下面的notes.rewriteRef
。此设置可以通过
GIT_NOTES_REWRITE_REF
环境变量覆盖,该变量必须是一个以冒号分隔的引用或 glob 列表。 notes.rewriteMode
-
在重写期间复制备注时(参见
notes.rewrite.
<command> 选项),确定如果目标提交已有备注时该怎么做。必须是overwrite
、concatenate
、cat_sort_uniq
或ignore
之一。默认为concatenate
。此设置可以通过
GIT_NOTES_REWRITE_MODE
环境变量覆盖。 notes.rewriteRef
-
在重写期间复制备注时,指定(完全限定的)要复制备注的引用。可以是一个 glob,在这种情况下,所有匹配引用中的备注都将被复制。您也可以多次指定此配置。
没有默认值;您必须配置此变量才能启用备注重写。将其设置为
refs/notes/commits
以启用默认提交备注的重写。可以通过
GIT_NOTES_REWRITE_REF
环境变量覆盖。有关其格式的进一步描述,请参见上面的notes.rewrite.
<command>。