Git

名称

git-replay - 实验性:在新的基础上重放提交,也适用于裸仓库

概要

(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 操作)。

<revision-range>

要重放的提交范围。可以传递多个 <revision-range>,但在 --advance <branch> 模式下,它们应该只有一个顶端,以便清楚地知道 <branch> 应该指向哪里。请参阅 git-rev-parse[1] 中的“指定范围”以及下面的“提交限制”选项。

提交限制

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

通常,使用更多选项会进一步限制输出(例如,--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 之前使用时,通过 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/headsrefs/tagsrefs/remotes开头,并且在应用于--glob--all时必须以refs/开头。如果需要尾随/*,则必须显式给出。

--exclude-hidden=[fetch|receive|uploadpack]

不包括git-fetchgit-receive-packgit-upload-pack通过参考相应的fetch.hideRefsreceive.hideRefsuploadpack.hideRefs配置以及transfer.hideRefs(参见git-config[1])隐藏的引用。此选项会影响下一个伪引用选项--all--glob,并在处理它们后清除。

--reflog

假设所有由 reflog 提及的对象都作为<commit>列在命令行上。

--alternate-refs

假设所有作为备用存储库的引用提示提到的对象都列在命令行上。备用存储库是指其对象目录在objects/info/alternates中指定的任何存储库。包含的对象集可以通过core.alternateRefsCommand等修改。参见git-config[1]

--single-worktree

默认情况下,当有多个工作树时(参见git-worktree[1]),以下选项将检查所有工作树:--all--reflog--indexed-objects。此选项强制它们仅检查当前工作树。

--ignore-missing

在输入中看到无效的对象名称时,假设未给出错误的输入。

--bisect

假设错误的二分查找引用refs/bisect/bad已列出,并且假设它后面跟着--not和良好的二分查找引用refs/bisect/good-*在命令行上。

--stdin

除了从命令行获取参数外,还可以从标准输入中读取参数。这接受提交和类似--all--glob=的伪选项。当看到--分隔符时,以下输入将被视为路径并用于限制结果。通过标准输入读取的--not之类的标志仅在其以相同方式传递的参数中受到尊重,并且不会影响任何后续的命令行参数。

--cherry-mark

类似于--cherry-pick(见下文),但用=标记等效提交,而不是省略它们,用+标记不等效提交。

--cherry-pick

当使用对称差集限制提交集时,省略任何引入与“另一侧”上的另一个提交相同更改的提交。

例如,如果您有两个分支AB,列出它们一侧的所有提交的常用方法是使用--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 条目遍历到旧的条目。使用此选项时,您不能指定要排除的提交(即,不能使用^commitcommit1..commit2commit1...commit2表示法)。

使用除了onelinereference之外的--pretty格式(出于显而易见的原因),这会导致输出包含从 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>的提交。但是历史简化有两个部分,一部分是选择提交,另一部分是如何执行,因为有各种策略可以简化历史记录。

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

<paths>

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

--simplify-by-decoration

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

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

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

默认模式

将历史记录简化为解释树最终状态的最简单历史记录。最简单,因为它会在最终结果相同的情况下修剪一些分支(即合并具有相同内容的分支)

--show-pulls

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

--full-history

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

--dense

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

--sparse

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

--simplify-merges

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

--ancestry-path[=<commit>]

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

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

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

  • X是一个独立的根提交,添加了一个新文件sideY修改了它。YX是TREESAME。它的合并Qside添加到P中,QP是TREESAME,但对Y不是。

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

默认模式

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

这将导致

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

请注意,仅跟踪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后代的D..M的子集,即排除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是通过忽略Mfile.txt的内容并仅采用file.txtX处的内容来创建的。因此,RX是TREESAME,但对M不是。最后,创建N的自然合并解析是采用file.txtR处的内容,因此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--'

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

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

提交排序

默认情况下,提交按逆时间顺序显示。

--date-order

在所有子节点显示之前不显示父节点,但在其他情况下按提交时间戳顺序显示提交。

--author-date-order

在所有子节点显示之前不显示父节点,但在其他情况下按作者时间戳顺序显示提交。

--topo-order

在所有子节点显示之前不显示父节点,并避免在历史记录的多条线上显示混合的提交。

例如,在如下所示的提交历史记录中

    ---1----2----4----7
	\	       \
	 3----5----6----8---

其中数字表示提交时间戳的顺序,带有--date-ordergit rev-list及其相关命令会按时间戳顺序显示提交:8 7 6 5 4 3 2 1。

使用--topo-order,它们将显示 8 6 5 3 7 4 2 1(或 8 7 4 2 6 5 3 1);为了避免显示来自两个并行开发轨道的提交混合在一起,一些较旧的提交会在较新的提交之前显示。

--reverse

以相反的顺序输出选择显示的提交(请参阅上面的“提交限制”部分)。不能与--walk-reflogs组合使用。

对象遍历

这些选项主要针对 Git 仓库的打包。

--no-walk[=(sorted|unsorted)]

仅显示给定的提交,但不遍历其祖先。如果指定了范围,则此选项无效。如果给出了参数unsorted,则提交将按命令行上给出的顺序显示。否则(如果给出了sorted或未给出参数),则提交将按提交时间以逆时间顺序显示。不能与--graph组合使用。

--do-walk

覆盖之前的--no-walk

提交格式化

--pretty[=<format>]
--format=<format>

以给定格式漂亮打印提交日志的内容,其中<format>可以是onelineshortmediumfullfullerreferenceemailrawformat:<string>tformat:<string>之一。当<format>不是上述任何一种,并且其中包含%placeholder时,它的行为就像给出了--pretty=tformat:<format>一样。

请参阅“PRETTY 格式”部分,了解每种格式的其他详细信息。当省略=<format>部分时,默认为medium

注意:您可以在仓库配置中指定默认的漂亮格式(请参阅git-config[1])。

--abbrev-commit

不显示完整的 40 字节十六进制提交对象名称,而是显示一个唯一命名对象的名称前缀。"--abbrev=<n>"(如果显示,也会修改 diff 输出)选项可用于指定前缀的最小长度。

这使得 "--pretty=oneline" 对使用 80 列终端的用户来说更容易阅读。

--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 个空格(即默认的mediumfullfuller)的漂亮格式中,会扩展制表符。

--notes[=<ref>]

显示注释提交的注释(请参阅git-notes[1]),当显示提交日志消息时。当命令行上没有给出--pretty--format--oneline选项时,这是git loggit showgit whatchanged命令的默认设置。

默认情况下,显示的注释来自core.notesRefnotes.displayRef变量中列出的注释 ref(或相应的环境覆盖)。请参阅git-config[1]了解更多详细信息。

使用可选的<ref>参数,使用 ref 查找要显示的注释。当 ref 以refs/notes/开头时,它可以指定完整的 refname;当它以notes/开头时,会加上refs/,否则会加上refs/notes/以形成 ref 的完整名称。

可以组合多个 --notes 选项来控制显示哪些注释。例如:"--notes=foo" 将仅显示来自"refs/notes/foo"的注释;"--notes=foo --notes" 将显示来自"refs/notes/foo"和默认注释 ref 的注释。

--no-notes

不显示注释。这会通过重置显示注释的注释 ref 列表来否定上面的--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 小时前”。-local选项对--date=relative无效。

--date=local--date=default-local的别名。

--date=iso(或--date=iso8601)以类似 ISO 8601 的格式显示时间戳。与严格的 ISO 8601 格式的区别在于

  • 使用空格代替T日期/时间分隔符

  • 时间和时区之间使用空格分隔

  • 时区的小时和分钟之间不使用冒号

--date=iso-strict(或--date=iso8601-strict)以严格的 ISO 8601 格式显示时间戳。

--date=rfc(或--date=rfc2822)以 RFC 2822 格式显示时间戳,通常在电子邮件中找到。

--date=short仅显示日期,而不显示时间,格式为YYYY-MM-DD

--date=raw将日期显示为自纪元(1970-01-01 00:00:00 UTC)以来的秒数,后面跟着一个空格,然后是相对于 UTC 的时区偏移量(一个+-,后面跟着四个数字;前两个是小时,后两个是分钟)。也就是说,就像时间戳是用strftime("%s %z")格式化的一样)。请注意,-local选项不影响自纪元以来的秒数(始终以 UTC 测量),但会切换附带的时区值。

--date=human如果时区与当前时区不匹配,则显示时区,如果日期匹配则不打印整个日期(例如,对于“今年”的日期跳过打印年份,如果日期在过去几天内并且我们可以只说星期几,则跳过整个日期本身)。对于较旧的日期,还会省略小时和分钟。

--date=unix将日期显示为 Unix 纪元时间戳(自 1970 年以来的秒数)。与--raw一样,这始终以 UTC 为单位,因此-local无效。

--date=format:...将格式...馈送到您的系统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[=<barrier>]

当不使用 --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,它可以是一个或多个(支持同时重新设置多个分支的基础)。

退出状态

对于成功的、无冲突的重放,退出状态为 0。当重放有冲突时,退出状态为 1。如果重放由于某种错误而无法完成(或开始),则退出状态将不是 0 或 1。

示例

要简单地将mybranch重新设置到target的基础上

$ git replay --onto target origin/main..mybranch
update refs/heads/mybranch ${NEW_mybranch_HASH} ${OLD_mybranch_HASH}

要将mybranch中的提交 cherry-pick 到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}

这将同时重新设置branch1branch2branch3的基础,它们自base以来所做的所有提交,并将它们放在origin/main之上。这三个分支可能在base之上有共同的提交,但并非必须如此。

Git

git[1] 套件的一部分

scroll-to-top