设置和配置
获取和创建项目
基本快照
分支与合并
共享和更新项目
检查和比较
打补丁
调试
电子邮件
外部系统
服务器管理
指南
管理
底层命令
- 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.45.1 → 2.47.3 无更改
-
2.45.0
2024-04-29
- 2.44.1 → 2.44.4 无更改
-
2.44.0
2024-02-23
概要
(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance <branch>) <revision-range>…
描述
获取提交范围并将其重放到新位置。不修改工作区和索引,也不更新任何引用。此命令的输出旨在用作 git
update-ref
--stdin
的输入,该命令将更新相关的分支(参见下面的输出部分)。
此命令是实验性的。其行为可能会发生变化。
选项
- --onto <newbase>
-
创建新提交的起始点。可以是任何有效的提交,而不仅仅是现有的分支名称。
当指定
--onto
时,输出中的 update-ref 命令将更新修订范围内的分支以指向新的提交,类似于git
rebase
--update-refs
更新受影响范围内的多个分支的方式。 - --advance <branch>
-
创建新提交的起始点;必须是分支名称。
当指定
--advance
时,输出中的 update-ref 命令将更新作为--advance
参数传递的分支以指向新的提交(换句话说,这模仿了一个 cherry-pick 操作)。 - <修订范围>
-
要重放的提交范围。可以传递多个 <修订范围>,但在
--advance
<branch> 模式下,它们应该有一个单一的尖端,以便清楚 <branch> 应该指向何处。请参阅 git-rev-parse[1] 中的“指定范围”和下面的“限制提交”选项。
提交限制
除了使用描述中解释的特殊符号指定应列出的提交范围外,还可以应用额外的提交限制。
通常,使用更多选项会进一步限制输出(例如,--since=
<date1> 将提交限制在比 <date1> 更新的提交,并且将其与 --grep=
<pattern> 一起使用会进一步限制到日志消息中有一行与 <pattern> 匹配的提交),除非另有说明。
请注意,这些是在提交排序和格式化选项(如 --reverse
)之前应用的。
- -<数量>
- -n <数量>
- --max-count=<数量>
-
限制输出的提交数量。
- --skip=<数量>
-
在开始显示提交输出之前跳过 number 个提交。
- --since=<日期>
- --after=<日期>
-
显示特定日期之后的所有提交。
- --since-as-filter=<日期>
-
显示特定日期之后的所有提交。这将遍历范围内的所有提交,而不是在遇到第一个比特定日期更旧的提交时停止。
- --until=<日期>
- --before=<日期>
-
显示特定日期之前的所有提交。
- --author=<模式>
- --committer=<模式>
-
限制提交输出为作者/提交者头行与指定模式(正则表达式)匹配的提交。如果使用多个
--author=
<pattern>,则选择作者与任一给定模式匹配的提交(对于多个--committer=
<pattern> 类似)。 - --grep-reflog=<模式>
-
限制提交输出为 reflog 条目与指定模式(正则表达式)匹配的提交。如果使用多个
--grep-reflog
,则选择 reflog 消息与任一给定模式匹配的提交。除非正在使用--walk-reflogs
,否则使用此选项是错误的。 - --grep=<模式>
-
限制提交输出为日志消息与指定模式(正则表达式)匹配的提交。如果使用多个
--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=<数量>
- --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
-
在查找要排除的提交时(使用 *^*),遇到合并提交时只追溯第一个父提交。这可以用于查找主题分支从与远程分支分歧点开始的更改集,因为任意合并都可以是有效的主题分支更改。
- --not
-
反转所有后续修订说明符的 *^* 前缀(或缺乏前缀)的含义,直到下一个
--not
。当在命令行中在 --stdin 之前使用时,通过标准输入传递的修订版本不会受其影响。相反,当通过标准输入传递时,命令行中传递的修订版本不会受其影响。 - --all
-
假装
refs/
中的所有引用以及HEAD
都作为 <commit> 列在命令行上。 - --branches[=<模式>]
-
假装
refs/heads
中的所有引用都以 <commit> 的形式在命令行中列出。如果给出 <pattern>,则将分支限制为匹配给定 shell glob 的分支。如果模式缺少 ?、* 或 [,则隐含在末尾添加 /*。 - --tags[=<模式>]
-
假装
refs/tags
中的所有引用都以 <commit> 的形式在命令行中列出。如果给出 <pattern>,则将标签限制为匹配给定 shell glob 的标签。如果模式缺少 ?、* 或 [,则隐含在末尾添加 /*。 - --remotes[=<模式>]
-
假装
refs/remotes
中的所有引用都以 <commit> 的形式在命令行中列出。如果给出 <pattern>,则将远程跟踪分支限制为匹配给定 shell glob 的分支。如果模式缺少 ?、* 或 [,则隐含在末尾添加 /*。 - --glob=<全局模式>
-
假装所有匹配 shell glob <glob-pattern> 的引用都以 <commit> 的形式在命令行中列出。如果缺少前导 refs/,则会自动添加。如果模式缺少 ?、* 或 [,则隐含在末尾添加 /*。
- --exclude=<全局模式>
-
不包括与 <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
选项描述中的示例)。但是,它会显示从另一个分支挑选出来的提交(例如,“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 符号)。
除了
oneline
和reference
(原因显而易见)之外,使用--pretty
格式时,输出将包含从 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[=<提交>]
-
当给定要显示的提交范围(例如 commit1..commit2 或 commit2 ^commit1),并且该范围中有一个提交 <commit> 时,仅显示该范围中是 <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
。通过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
。 -
将
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> 本身。
作为一个示例用例,考虑以下提交历史:
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
后代的 D..M 子集,即排除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
不是。最后,创建 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 但与其后续父级是 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> 可以是 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=<编码>
-
提交对象在其编码头中记录了用于日志消息的字符编码;此选项可用于告诉命令以用户偏好的编码重新编码提交日志消息。对于非底层命令,这默认为 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[=<引用>]
-
在显示提交日志消息时,显示注释提交的附注(参见 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[=<引用>]
- --[no-]standard-notes
-
这些选项已弃用。请改用上面的 --notes/--no-notes 选项。
- --show-signature
-
通过将签名传递给
gpg
--verify
并显示输出来检查已签名提交对象的有效性。 - --relative-date
-
等同于
--date=relative
。 - --date=<格式>
-
仅对以人类可读格式显示的日期有效,例如使用
--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" 格式的小时-分钟-秒,后跟 4 位年份,以及时区信息,除非使用本地时区,例如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[=<分隔符>]
-
当不使用 --graph 时,所有历史分支都会被扁平化,这可能使得难以看出两个连续的提交不属于线性分支。在这种情况下,此选项会在它们之间放置一个分隔符。如果指定了 <barrier>,它将是代替默认字符串显示的字符串。
输出
当没有冲突时,此命令的输出可用作 git
update-ref
--stdin
的输入。其形式为:
update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH} update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH} update refs/heads/branch3 ${NEW_branch3_HASH} ${OLD_branch3_HASH}
其中更新的引用数量取决于传递的参数和正在重放的历史形状。当使用 --advance
时,更新的引用数量始终为一,但对于 --onto
,可以是一个或多个(支持同时对多个分支进行变基)。
示例
简单地将 mybranch
变基到 target
上:
$ git replay --onto target origin/main..mybranch update refs/heads/mybranch ${NEW_mybranch_HASH} ${OLD_mybranch_HASH}
将 mybranch 的提交挑选到 target 上:
$ git replay --advance target origin/main..mybranch update refs/heads/target ${NEW_target_HASH} ${OLD_target_HASH}
请注意,前两个示例重放了完全相同的提交,并且是在完全相同的新基准之上,它们的唯一区别在于第一个提供了使 mybranch 指向新提交的指令,而第二个提供了使 target 指向它们的指令。
如果您有一堆相互依赖的分支,并且您真的想对整个集合进行变基怎么办?
$ git replay --contained --onto origin/main origin/main..tipbranch update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH} update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH} update refs/heads/tipbranch ${NEW_tipbranch_HASH} ${OLD_tipbranch_HASH}
调用 git
replay
时,不需要使用 A..B
语法指定要重放的提交范围;任何范围表达式都可以:
$ git replay --onto origin/main ^base branch1 branch2 branch3 update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH} update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH} update refs/heads/branch3 ${NEW_branch3_HASH} ${OLD_branch3_HASH}
这将同时变基 branch1
、branch2
和 branch3
,将它们自 base
以来所有的提交重放到 origin/main
之上。这三个分支可能在 base
之上有共同的提交,但这并非必须如此。