Git
简体中文 ▾ Topics ▾ Latest version ▾ git-log last updated in 2.38.1

名称

git-log - 显示提交日志

概述

git log [<options>] [<revision-range>] [[--] <path>…​]

描述

显示提交日志。

Warning

Missing zh_HANS-CN/rev-list-description.txt

See original version for this content.

该命令采用适用于 git-rev-list[1] 命令的选项来控制显示的内容和方式,以及适用于 git-diff[1] 命令的选项来控制每次提交引入的更改的显示方式。

选项

--follow

继续列出一个文件的历史,超过重命名(只对单个文件有效)。

--no-decorate
--装饰[=短|全|自动|无]

Print out the ref names of any commits that are shown. If short is specified, the ref name prefixes refs/heads/, refs/tags/ and refs/remotes/ will not be printed. If full is specified, the full ref name (including prefix) will be printed. If auto is specified, then if the output is going to a terminal, the ref names are shown as if short were given, otherwise no ref names are shown. The option --decorate is short-hand for --decorate=short. Default to configuration value of log.decorate if configured, otherwise, auto.

--decorate-refs=<pattern>
--decorate-refs-exclude=<pattern>

For each candidate reference, do not use it for decoration if it matches any patterns given to --decorate-refs-exclude or if it doesn’t match any of the patterns given to --decorate-refs. The log.excludeDecoration config option allows excluding refs from the decorations, but an explicit --decorate-refs pattern will override a match in log.excludeDecoration.

If none of these options or config settings are given, then references are used as decoration if they match HEAD, refs/heads/, refs/remotes/, refs/stash/, or refs/tags/.

--clear-decorations

When specified, this option clears all previous --decorate-refs or --decorate-refs-exclude options and relaxes the default decoration filter to include all references. This option is assumed if the config value log.initialDecorationSet is set to all.

--source

打印出命令行上给出的每一次提交所依据的参考名称。

--[no-]mailmap
--[no-]use-mailmap

使用 mailmap 文件将作者和提交者的名字和电子邮件地址映射为规范的真实姓名和电子邮件地址。参见 git-shortlog[1]

--full-diff

没有这个标志,`git log -p <path>…​`会显示触及指定路径的提交,以及关于相同指定路径的差异。 有了这个,就会显示触及指定路径的提交的全部差异;这意味着"<path>…​ "只限制提交,而不限制这些提交的差异。

请注意,这将影响所有基于diff的输出类型,例如那些由`--stat`产生的输出。

--log-size

在每次提交的输出中包括一行"‘日志大小<number>’",其中<number>是该提交信息的长度,单位为字节。 旨在加快从`git log`输出中读取日志信息的工具的速度,允许它们提前分配空间。

Warning

Missing zh_HANS-CN/line-range-options.txt

See original version for this content.

<revision-range>

Show only commits in the specified revision range. When no <revision-range> is specified, it defaults to HEAD (i.e. the whole history leading to the current commit). origin..HEAD specifies all the commits reachable from the current commit (i.e. HEAD), but not from origin. For a complete list of ways to spell <revision-range>, see the Specifying Ranges section of gitrevisions[7].

[--] <路径>…​

只显示那些足以解释符合指定路径的文件是如何形成的提交。 有关细节和其他简化模式,请参见下面的’历史简化'。

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

承诺限制

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

使用更多的选项通常会进一步限制输出(例如,--since=<date1>`限制在比<date1>新的提交,与--grep=<pattern>一起使用会进一步限制在日志信息中有一行符合<pattern>`的提交),除非另有说明。

请注意,这些都是在提交排序和格式化选项之前应用的,如`--反转`。

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

限制输出的提交数量。

--skip=<number>

在开始显示提交输出之前,跳过’数’的提交。

--since=<date>
--after=<日期>

显示比某一特定日期更近的提交。

--since-as-filter=<date>

Show all commits more recent than a specific date. This visits all commits in the range, rather than stopping at the first commit which is older than a specific date.

--until=<日期>
--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`)。

当`--笔记`生效时,笔记中的信息被匹配,就像它是日志信息的一部分。

--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 and --no-max-parents reset these limits (to no limit) again. Equivalent forms are --min-parents=0 (any commit has 0 or more parents) and --max-parents=-1 (negative numbers denote no upper limit).

--first-parent

When finding commits to include, follow only the first parent commit upon seeing a merge commit. This option can give a better overview when viewing the evolution of a particular topic branch, because merges into a topic branch tend to be only about adjusting to updated upstream from time to time, and this option allows you to ignore the individual commits brought in to your history by such a merge.

这个选项也改变了合并提交的默认差异格式为 "first-parent",详见"-diff-merges=first-parent"。

--exclude-first-parent-only

When finding commits to exclude (with a ^), follow only the first parent commit upon seeing a merge commit. This can be used to find the set of changes in a topic branch from the point where it diverged from the remote branch, given that arbitrary merges can be valid topic branch changes.

--not

颠倒"^"前缀(或没有前缀)对所有后续修订指定符的意义,直到下一个`--not`。

--all

假设`refs/‘中的所有参考文献,连同`HEAD`一起,在命令行中被列为’<commit>'。

--支部[=<模式>]

假设`refs/heads`中的所有 refs 在命令行中被列为 <commit>。如果给出了'<pattern>',将分支限制在与给定的shell glob相匹配的分支。如果pattern缺少'?*'或'[,则末尾的/*'是暗示的。

--tags[=<pattern>]

假设`refs/tags`中的所有参考文献在命令行中被列为'<commit>'。如果给出了'<pattern>',将标签限制在与给定的shell glob相匹配的标签。如果pattern缺少'?*'或'[,则暗示最后的/*'。

--remotes[=<pattern>]

假设`refs/remotes`中的所有 refs 在命令行中被列为 <commit>。如果给出了'<pattern>',将远程跟踪分支限制在与给定的shell glob相匹配的分支。 如果pattern缺少'?*'或'[,则末尾的/*'是暗示的。

--glob=<glob-pattern>

假设所有与shell glob <glob-pattern>相匹配的refs在命令行中被列为<commit>'。前面的’refs/,如果缺少的话会自动预加。如果模式中缺少?*'或'[,则在结尾处隐含/*'。

--exclude=<glob-pattern>(排除)。

不包括匹配"<glob-pattern>"的参考文献,否则下一个`--all`、--branches--tags--remotes`或--glob`会考虑这些参考文献。重复这个选项可以累积排除模式,直到下一个`----all`、---branches---tags---remotes`或---glob`选项(其他选项或参数不清除累积模式)。

当应用于"--分支"、"--标签 "或"--远程 "时,给出的模式不应该以 "refs/heads"、"refs/tags "或 "refs/remotes "开头,而当应用于"--glob "或 "all "时,必须以 "refs/"开头。如果打算使用尾部的"/*",必须明确给出。

--reflog

假设reflogs提到的所有对象都在命令行中被列为`<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

除了命令行上列出的'<commit>'之外,还要从标准输入中读取它们。如果看到`--`分隔符,就停止读取提交,开始读取路径以限制结果。

--cherry-mark

就像`--cherry-pick`(见下文),但用`=标记同等的提交,而不是省略,用+`标记不同等的提交。

--cherry-pick

当提交的集合有对称差异时,省略任何与 "另一边 "的另一个提交相同的提交。

例如,如果你有两个分支,A`和`B,通常的方法是用`--左—​右`列出其中一边的所有提交(见下面关于`--左—​右`选项的描述)。然而,它显示的是从另一个分支中偷梁换柱的提交(例如,"3rd on b "可能是从分支A中偷梁换柱的)。有了这个选项,这样的提交对将从输出中排除。

--left-only
--right-only

只列出对称性差异各自一侧的提交,即只列出那些通过"--左—​右 "标记的"<"或">"。

例如,--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}(带有该条目的时间戳),取决于一些规则。

  1. 如果起点被指定为`ref@{Nth}`,显示索引格式。

  2. 如果起点被指定为`ref@{now}`,显示时间戳格式。

  3. 如果两者都没有使用,但在命令行中给出了`--date`,则按照`--date`所要求的格式显示时间戳。

  4. 否则,显示索引格式。

在`--pretty=oneline`下,提交信息的前缀是同一行中的这些信息。 这个选项不能与 `--reverse`结合使用。 参见 git-reflog[1]

在`--pretty=reference`下,这些信息将完全不显示。

--merge

在合并失败后,显示触及有冲突的文件且不存在于所有要合并的头的参考文件。

--boundary

输出排除的边界提交。边界提交的前缀是"-"。

简化历史

有时你只对历史的一部分感兴趣,例如修改某个<路径>的提交。但 "历史简化 "有两部分,一部分是选择提交,另一部分是如何做,因为有各种策略来简化历史。

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

<paths>

修改给定<路径>的提交会被选中。

--simplify-by-decoration

被某个分支或标签引用的提交被选中。

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

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

Default mode

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

--show-pulls

包括默认模式下的所有提交,但也包括任何与第一个父分支不相干但与后来的父分支相干的合并提交。这种模式有助于显示 "首次引入 "某个分支的合并提交。

--full-history

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

--dense

只显示所选的提交,再加上一些才有意义的历史。

--sparse

简化历史中的所有提交都会显示出来。

--simplify-merges

为`--full-history`增加了一个选项,可以从结果的历史中删除一些不必要的合并,因为没有选定的提交对这次合并有贡献。

--ancestry-path[=<commit>]

When given a range of commits to display (e.g. commit1..commit2 or commit2 ^commit1), only display commits in that range that are ancestors of <commit>, descendants of <commit>, or <commit> itself. If no commit is specified, use commit1 (the excluded part of the range) as <commit>. Can be passed multiple times; if so, a commit is included if it is any of the commits given or if it is an ancestor or descendant of one of them.

以下是更详细的解释。

假设你指定了`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`是一个独立的根提交,添加了一个新文件`sideY`修改了它。`Y`与`X`同为TREESAME。它的合并文件`Q`在`P`上添加了`side,`Q`与`P`是同源,但与`Y`不是同源。

rev-list`在历史中倒退,根据是否使用--full-history`和/或父代重写(通过`--parents`或`--children`),包括或排除提交。以下设置是可用的。

Default mode

如果提交的内容与任何父类不相干,则被包括在内(当然这一点可以改变,见下面的`--sparse`)。 如果该提交是一个合并,并且它与一个父类是同源的,则只跟随该父类。 (即使有几个TREESAME父类,也只跟随其中一个。) 否则,跟随所有父类。

This results in:

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

请注意,如果有TREESAME父类的话,只遵循TREESAME父类的规则,将`B’完全排除在考虑之外。 `C`是通过`N`考虑的,但也是TREESAME。 根提交是与空树比较的,所以`I`是!!TREESAME。

父/子关系只有在`--父母`的情况下才能看到,但这并不影响在默认模式下选择的提交,所以我们显示了父行。

--full-history without parent rewriting

这种模式与默认模式有一点不同:总是跟随一个合并的所有父本,即使它与其中一个父本是TREESAME。 即使合并的一方有多个提交被包括在内,这也不意味着合并本身也是如此在这个例子中,我们得到

	I  A  B  N  D  O  P  Q

‘M’被排除在外,因为它与父母都是TREESAME。 `E’、`C’和`B’都走了,但只有`B’是!"TREESAME",所以其他的都没有出现。

请注意,如果没有父子重写,其实是不可能谈论提交之间的父子关系的,所以我们显示它们是不相连的。

--full-history with parent rewriting

普通的提交只有当它们是!TREESAME时才会被包括在内(尽管这一点可以改变,见下面的`--sparse`)。

合并总是被包括在内。 然而,他们的父级列表会被重写。沿着每个父级,修剪掉那些不包括自己的提交。 这样做的结果是

	  .-A---M---N---O---P---Q
	 /     /   /   /   /
	I     B   /   D   /
	 \   /   /   /   /
	  `-------------'

与上面的`--full-history`相比,没有重写。 请注意,E`被修剪掉了,因为它是TREESAME,但是P的父列表被改写为包含`E`的父`I。 同样的情况发生在`C`和`N`,以及`X`、Y`和`Q

除了上述设置外,你还可以改变TRESAME是否会影响收录。

--dense

如果不与任何父类有TREESAME关系,则包括走过的承诺。

--sparse

所有走过的提交都包括在内。

请注意,如果没有`--full-history`,这仍然可以简化合并:如果父代之一是TREESAME,我们只跟随这个父代,所以合并的其他方面永远不会被走。

--simplify-merges

首先,按照`--full-history`与父级改写的相同方式建立一个历史图(见上文)。

然后根据以下规则将每个提交的`C’简化为最终历史中的替换`C'。

  • 将 "C "设为 "C"。

  • 将`C'的每个父类`P'替换成其简化的`P'。 在这个过程中,放弃那些是其他父类的祖先的父类,或者是根部提交TREESAME的空树,并删除重复的父类,但注意不要放弃所有我们是TREESAME的父类。

  • 如果在这次父级改写之后,‘C’`是一个根或合并提交(有0个或>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>]

Limit the displayed commits to those which are an ancestor of <commit>, or which are a descendant of <commit>, or are <commit> itself.

作为一个用例,请考虑以下提交历史。

	    D--E-------F
	   / \ \
	  B---C---G---H---I---J
	 / \
	A-------K---------------L--M

有规律的 "D…​M "会计算出作为`M`的祖先的提交集合,但不包括作为`D`的祖先的提交。这对了解`M’的历史在`D’之后发生了什么很有用,也就是说`M’有什么东西是`D’没有的'。这个例子中的结果是所有的提交,除了`A`和`B`(当然还有`D`本身)。

然而,当我们想找出`M’中哪些提交被`D’引入的错误所污染而需要修复时,我们可能只想查看’D…​M’中实际上是`D’的后代的子集,即排除`C’和`K'。这正是`--ancestry-path`选项的作用。应用于’D…​M’范围,它的结果是:

		E-------F
		 \ \
		  G--H--I--J
			       \
				L--M

We can also use --ancestry-path=D instead of --ancestry-path which means the same thing when applied to the D..M range but is just more explicit.

If we instead are interested in a given topic within this range, and all commits affected by that topic, we may only want to view the subset of D..M which contain that topic in their ancestry path. So, using --ancestry-path=H D..M for example would result in:

		E
		 \
		  G---H---I---J
			       \
				L--M

Whereas --ancestry-path=K D..M would result in

		K---------------L--M

在讨论另一个选项,`--显示—​推力’之前,我们需要创建一个新的历史实例。

用户在查看简化历史时经常遇到的一个问题是,他们知道的对某个文件的修改提交并没有出现在该文件的简化历史中。让我们演示一个新的例子,并说明`--full-history`和`--simplify-merges`等选项在这种情况下是如何工作的。

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

在这个例子中,假设`I`创建了`file.txt`,并被`A`、B`和`X`以不同方式修改。单亲提交的`CZ`和`Y`没有修改`file.txt。合并提交 "M "是通过解决合并冲突而产生的,包括了 "A "和 "B "的修改,因此与其中任何一个都不是同源的。然而,合并提交`R`是通过忽略`M`处的`file.txt`的内容,而只采用`X`处的`file.txt`的内容而产生的。因此,R`与`X`是同源的,但不是`M。最后,创建`N’的自然合并决议是取`file.txt`在`R’的内容,所以`N’与`R’是同源的,但不是`C'。 合并提交的 "O "和 "P "与它们的第一代父母是同源的,但与它们的第二代父母 "Z "和 "Y "则不是同源的。

当使用默认模式时,`N’和`R’都有一个TREESAME父级,所以这些边被走,其他的被忽略。由此产生的历史图是。

	I--X

当使用`--full-history`时,Git会行走每条边。这将发现提交`A`和`B`以及合并`M`,但也将揭示合并提交`O`和`P`。通过父级改写,得到的图是。

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

Here, the merge commits O and P contribute extra noise, as they did not actually contribute a change to file.txt. They only merged a topic that was based on an older version of file.txt. This is a common issue in repositories using a workflow where many contributors work in parallel and merge their topic branches along a single trunk: many unrelated merges appear in the --full-history results.

当使用`--简化合并`选项时,提交的`O`和`P`从结果中消失。这是因为 "O "和 "P "重写的第二父本可以从它们的第一父本到达。这些边被移除,然后这些提交看起来就像与它们的父类一样的单亲提交。这也发生在提交`N`上,导致历史视图如下。

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

在这个视图中,我们看到了所有来自`A`,B`和`X`的重要单亲变化。我们还可以看到仔细解决的合并`M`和不那么仔细解决的合并`R。这些信息通常足以确定为什么`A`和`B`的提交在默认视图中从历史中 "消失 "了。然而,这种方法也有一些问题。

第一个问题是性能。与之前的任何选项不同,`--简化合并’选项需要在返回一个结果之前走完整个提交历史。这可能使该选项难以用于非常大的仓库。

第二个问题是审计的问题。当许多贡献者在同一个版本库中工作时,哪些合并提交将一个变化引入到一个重要的分支是很重要的。上面有问题的合并`R`不可能是用来合并到一个重要分支的合并提交。相反,`N’是用来将`R’和`X’合并到重要分支的。这个提交可能有关于为什么`X’会覆盖`A’和`B’的修改的信息,在其提交信息中。

--show-pulls

除了在默认历史中显示的提交之外,还要显示每一个与第一个父本不相同但与后来的父本相同的合并提交。

当一个合并提交被`--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`的修改 "拉 "进了主分支。

`--按装饰简化’选项允许你只查看历史拓扑的全貌,省略那些没有被标签引用的提交。 如果(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`结合使用。

对象遍历

这些选项主要是针对Git存储库的打包。

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

Only show the given commits, but do not traverse their ancestors. This has no effect if a range is specified. If the argument unsorted is given, the commits are shown in the order they were given on the command line. Otherwise (if sorted or no argument was given), the commits are shown in reverse chronological order by commit time. Cannot be combined with --graph.

--do-walk

覆盖之前的`--不走'。

承诺格式化

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

以指定的格式打印提交日志的内容,其中'<format>'可以是’oneline'、shortmediumfullfullerreferenceemailrawformat:<string>'和’tformat:<string>'之一。 当<format>'不是上述任何一种,并且其中有'%placeholder’时,它的作用就像给出'--pretty=tformat:<format>'一样。

参见 "PRETTY FORMATS "部分,了解每种格式的一些额外细节。 当'=<格式>'部分被省略时,它默认为’中等'。

注意:你可以在版本库配置中指定默认的漂亮格式(见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`输出的,我们将逐字输出该对象;这意味着原始提交中的无效序列可能会被复制到输出中。

--expand-tabs=<n>
--expand-tabs
--no-expand-tabs

在输出中显示之前,在日志信息中进行标签扩展(用足够的空格替换每个标签,以填充到下一个显示列的'<n>'的倍数)。 --expand-tabs`是--expand-tabs=8`的简写,--no-expand-tabs`是--expand-tabs=0`的简写,它禁止标签扩展。

默认情况下,标签会以漂亮的格式展开,将日志信息缩进4个空格(即 "中",这是默认的,"全",和 "更全")。

--notes[=<ref>]

在显示提交日志信息时,显示注释提交的说明(见git-notes[1])。 这是`git log`、git show`和`git whatchanged`命令的默认设置,当命令行中没有给出--pretty`、--format`或--oneline`选项时。

默认情况下,显示的注释来自于`core.notesRef`和`notes.displayRef`变量(或相应的环境覆盖)中列出的注释参考。更多细节见git-config[1]

有了一个可选的'<ref>'参数,就可以使用ref来寻找要显示的笔记。 当ref以`refs/notes/开头时,可以指定完整的ref名称;当它以`notes/`开头时,`refs/,否则`refs/notes/`前缀,形成ref的全名。

多个—​音符选项可以组合起来,控制哪些音符被显示。例如。"--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[=<ref>]
--[no-]standard-notes

这些选项已被废弃。请使用上面的 --notes/-no-notes 选项来代替。

--show-signature

通过将签名传递给 gpg --verify 来检查已签名的提交对象的有效性,并显示输出。

--relative-date

`--date=relative`的同义词。

--date=<format>

只对以人类可读格式显示的日期生效,例如使用`--pretty`时。log.date`配置变量为日志命令的--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:... feeds the format ... to your system strftime, except for %s, %z, and %Z, which are handled internally. Use --date=format:%c to show the date in your system locale’s preferred format. See the strftime manual for a complete list of format placeholders. When using -local, the correct syntax is --date=format-local:....

--date=default`是默认格式,与--date=rfc2822`类似,但有一些例外。

  • 在星期的后面没有逗号

  • 当使用本地时区时,省略了时区。

--parents

也可以打印提交的父类(以 "提交父类…​ "的形式)。 也可以启用父级改写,见上面的 "历史简化"。

--children

同时打印提交的子项(以 "提交子项…​ "的形式)。 也可以启用父级改写,见上面的 "历史简化"。

--left-right

标明提交可以从对称性差异的哪一边到达。 左边的提交以`<为前缀,右边的则以>`为前缀。 如果与"--边界 "结合,这些提交的前缀为"-"。

例如,如果你有这样的拓扑结构。

	     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-format不是 "oneline"、"email "或 "raw",那么在 "Author: "一行之前会插入一个附加行。 这一行的开头是 "Merge:这一行以 "Merge: "开头,并打印出祖先提交的哈希值,用空格分隔。 请注意,如果你限制了你的历史视图,那么列出的提交不一定是*直接*父级提交的列表:例如,如果你只对与某个目录或文件有关的修改感兴趣。

有几种内置的格式,你可以通过将 pretty.<name> 配置选项设置为另一种格式名称或 "format: "字符串来定义额外的格式,如下所述(见 git-config[1] )。下面是内置格式的细节。

  • oneline

    <hash> <title line>

    这个设计是为了尽可能的紧凑。

  • short

    承诺<hash>
    作者。<作者>的情况
    <title line>
  • medium

    承诺<hash>
    作者。<作者>的情况
    日期。   <作者>日期
    <title line>
    <完整的提交信息
  • full

    承诺<hash>
    作者。< Author>
    承诺。<committer>(提交者)。
    <title line>
    <完整的提交信息
  • fuller

    承诺<hash>
    作者。     <作者>的情况
    作者日期。<作者日期>。
    承诺。     <承诺者>
    提交日期。<提交者日期>
    <title line>
    <完整的提交信息
  • reference

    <abbrev hash>(<标题行>,<简短的作者日期>)。

    这种格式用于在提交信息中引用另一个提交,与`--pretty='format:%C(auto)%h (%s, %ad)'相同。 默认情况下,日期的格式为`--date=short`,除非明确指定其他`--date`选项。 与任何带有格式占位符的`format:一样,其输出不受其他选项的影响,如--decorate`和`--walk-reflogs`。

  • email

    来自<hash><date>的信息
    来自。<作者
    日期。<作者>日期
    主题。[PATCH] <标题行
    <完整的提交信息
  • mboxrd

    和 "email "一样,但提交信息中以 "From "开头的行(前面有零个或多个">")用">"引出,这样就不会被混淆为开始了一个新的提交。

  • raw

    原始 "格式显示的是整个提交对象中存储的内容。 值得注意的是,无论是否使用了 --abbrev 或 --no-abbrev,哈希值都会被完整地显示出来,而’parent’信息会显示真正的父级提交,不会考虑移花接木或历史简化。注意,这种格式会影响提交的显示方式,但不会影响diff的显示方式,比如用`git log --raw`来显示。要获得原始差异格式的完整对象名称,请使用`--no-abbrev`。

  • format:<string>

    format:<string>"格式允许你指定你想显示的信息。它的工作原理有点像printf格式,值得注意的是,你得到的换行是'%n’而不是'\n'。

    例如,'format: "The author of %h was %an, %ar%nThe title was >>%s<<%n"'会显示这样的内容。

    fe6e0ee的作者是Junio C Hamano, 23小时前
    标题是 >>t4119: 测试传统diff输入的自动计算-p<n>。

    占位符是。

    • 占位符,可扩展为一个字面字符。

      %n

      换行

      %%

      一个原始的'%'

      %x00

      打印十六进制代码中的一个字节

    • 影响后面占位符的格式化的占位符。

      %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)、中间(mtrunc)或结尾(trunc)进行截断。 注意,只有在N>=2的情况下,截断才会正常工作。

      %<|(<N>)

      使下一个占位符至少到第N列,必要时在右边填充空格

      %>(<N>), %>|(<N>)

      similar to %<(<N>), %<|(<N>) respectively, but padding spaces on the left

      %>>(<N>), %>>|(<N>)

      分别类似于'%>(<N>)%>|(<N>)',只是如果下一个占位符占用的空间比给定的多,并且其左侧有空格,则使用这些空格。

      %><(<N>), %><|(<N>)

      similar to %<(<N>), %<|(<N>) respectively, but padding both sides (i.e. the text is centered)

    • 占位符,扩展到从提交中提取的信息。

      %H

      commit hash

      %h

      简称提交哈希

      %T

      tree hash

      %t

      简称树形哈希

      %P

      父类哈希值

      %p

      缩写的父母哈希值

      %an

      author name

      %aN

      author name (respecting .mailmap, see git-shortlog[1] or git-blame[1])

      %ae

      author email

      %aE

      author email (respecting .mailmap, see git-shortlog[1] or git-blame[1])

      %al

      作者电子邮件的本地部分("@"符号之前的部分)。

      %aL

      author local-part (see %al) respecting .mailmap, see git-shortlog[1] or 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

      committer name

      %cN

      committer name (respecting .mailmap, see git-shortlog[1] or git-blame[1])

      %ce

      committer email

      %cE

      committer email (respecting .mailmap, see git-shortlog[1] or git-blame[1])

      %cl

      承诺人电子邮件的本地部分("@"符号之前的部分)。

      %cL

      committer local-part (see %cl) respecting .mailmap, see git-shortlog[1] or 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

      ref名称,就像git-log[1]的-decorate选项。

      %D

      没有"("、")"包装的参考文献名称。

      %(description[:options])

      人类可读的名字,像git-describe[1];空字符串表示不可描述的提交。 `describe`字符串后面可以有冒号和零个或多个逗号分隔的选项。 当标签同时被添加或删除时,描述可能不一致。

      • match=<pattern>:只考虑与给定的`glob(7)`模式匹配的标签,不包括 "refs/tags/"前缀。

      • exclude=<pattern>:不考虑匹配给定`glob(7)`模式的标签,排除 "refs/tags/"前缀。

      %S

      在命令行中给出的提交名称(如`git log --source`),只对`git log`起作用。

      %e

      encoding

      %s

      subject

      %f

      经过消毒的主题行,适合于文件名

      %b

      body

      %B

      原始体(未包装的主题和体)。

      %N

      承诺说明

      %GG

      来自GPG的签名提交的原始验证信息

      %G?

      显示 "G "代表一个好的(有效的)签名,"B "代表一个坏的签名,"U "代表一个有效性未知的好的签名,"X "代表一个已经过期的好的签名,"Y "代表一个由过期的钥匙制作的好的签名,"R "代表一个由撤销的钥匙制作的好的签名,"E "如果不能检查签名(如缺少钥匙),"N "代表没有签名。

      %GS

      显示已签名的提交的签名者的名字

      %GK

      显示用于签署已签名的承诺的密钥

      %GF

      显示用于签署已签名提交文件的密钥的指纹。

      %GP

      显示主键的指纹,该主键的子键被用来签署一个已签署的提交。

      %GT

      显示用于签署已签名的承诺的密钥的信任级别

      %gD

      reflog选择器,例如,refs/stash@{1}`或`refs/stash@{2分钟前};其格式遵循`-g`选项的规则。@'前面的部分是命令行上给出的参考文献名称(所以`git log -g refs/heads/master`会产生`refs/heads/master@{0})。

      %gd

      简化的 reflog 选择器;与 %gD 相同,但 refname 部分被缩短以利于人类阅读(因此 refs/heads/master 变成了 master)。

      %gn

      记录身份名称

      %gN

      reflog identity name (respecting .mailmap, see git-shortlog[1] or git-blame[1])

      %ge

      重新记录身份邮件

      %gE

      reflog identity email (respecting .mailmap, see git-shortlog[1] or git-blame[1])

      %gs

      记录主题

      %(trailer[:options])

      显示由git-interpret-trailers[1]解释的正文的预告片。`trailers`字符串后面可以有冒号和零个或多个逗号分隔的选项。 如果任何选项被多次提供,则最后出现的选项获胜。

      布尔选项接受一个可选的值`[=<BOOL>]。`true, false, on, `off`等值都可以接受。参见git-config[1]中 "示例 "的 "布尔 "子章节。如果一个布尔选项没有给出值,它就被启用。

      • key=<K>:只显示具有指定密钥的拖车。匹配是不分大小写的,后面的冒号是可选的。如果多次给出选项,则显示与任何键匹配的拖车行。该选项自动启用 "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>'相同。

Note
一些占位符可能取决于给修订版遍历引擎的其他选项。例如,%g* reflog选项将插入一个空字符串,除非我们正在遍历reflog条目(例如,通过`git log -g`)。%d`和%D`占位符将使用 "短 "装饰格式,如果`--decorate`没有在命令行上提供。

如果你在占位符的'%后面加了一个`+(加号),当且仅当占位符扩展为一个非空字符串时,在扩展前会立即插入换行符。

如果你在占位符的'%后面加了一个`-(减号),如果且仅当占位符扩展为空字符串时,紧接着扩展前的所有连续换行将被删除。

如果你在占位符的'%'后面加了一个``(空格),当且仅当占位符扩展到一个非空字符串时,空格就会紧接着插入扩展。

  • tformat:

    tformat: "格式的工作原理与 "format: "完全一样,只是它提供了 "终止符 "语义,而不是 "分隔符 "语义。换句话说,每个提交都附加了信息结束符(通常是换行符),而不是在条目之间放置一个分隔符。 这意味着单行格式的最后一个条目将正确地以新行结束,就像 "单行 "格式那样。 比如说

    $ 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`选项),否则合并提交不会显示差异,即使选择了`--patch`这样的差异格式,也不会匹配`-S`这样的搜索选项。例外情况是当`--first-parent`被使用时,在这种情况下,`first-parent`是默认格式。

Warning

Missing zh_HANS-CN/diff-options.txt

See original version for this content.

使用选项 -p 生成补丁文本

Running git-diff[1], git-log[1], git-show[1], git-diff-index[1], git-diff-tree[1], or git-diff-files[1] with the -p option produces patch text. You can customize the creation of patch text via the GIT_EXTERNAL_DIFF and the GIT_DIFF_OPTS environment variables (see git[1]), and the diff attribute (see gitattributes[5]).

-p 选项产生的内容与传统的差异格式略有不同:

  1. 它前面有一个 git diff 头,如下所示:

    diff --git a/file1 b/file2

    a/b/ 的文件名相同,除非涉及到重命名/复制。特别地,即使是创建或删除,也 使用 /dev/null 来代替 a/b/ 文件名。

    当涉及到重命名/复制时,file1file2 分别显示重命名/复制的源文件的名称和重命名/复制产生的文件的名称。

  2. 它的后面是一个或多个扩展头信息行:

    old mode <模式>
    new mode <模式>
    deleted file mode <模式>
    new file mode <模式>
    copy from <路径>
    copy to <路径>
    rename from <路径>
    rename to <路径>
    similarity index <数字>
    dissimilarity index <数字>
    index <哈希>..<哈希> <模式>

    文件模式被打印为6位八进制数字,包括文件类型和文件权限位。

    扩展头信息中的路径名称不包括 a/b/ 前缀。

    相似性指数是未改变的行占比,而不相似性指数是改变的行占比。它是四舍五入的整数,后有百分号。因此,100%的相似度指数指为两个文件相等,而 100% 的不相似度意味着入新文件中没有旧文件中的行。

    索引行包括改变前和改变后的 blob 对象名称。如果文件模式没有变化,则包含 <模式>;否则,分别显示新旧模式。

  3. 含有 "不常见" 字符的路径名会被引用,这一点在配置变量` core.quotePath` 中有所解释(见 git-config[1])。

  4. 输出中所有的 file1 文件都是指提交前的文件,而所有的 file2 文件都是指提交后的文件。按顺序对每个文件进行修改是不正确的。例如,这个补丁将交换文件 a 和 b:

    diff --git a/a b/b
    rename from a
    rename to b
    diff --git a/b b/a
    rename from b
    rename to a
  5. 块头提到了块头所适用的函数的名称。 参见 gitattributes[5] 中的 "定义自定义 hunk-header",以了解如何针对特定语言进行定制。

合并的差异格式

任何生成差异的命令都可以使用 -c-cc 选项,在显示合并时产生一个 "合并差异"。当用 git-diff[1]git-show[1] 显示合并时,这默认格式。还需要注意的是,你可以给这些命令适当的 --diff-merges 选项来强制生成特定格式的差异。

"合并的差异" 的格式如下:

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);
  1. 它前面有 "git diff" 头,如下(当使用 c 选项时):

    diff --combined file

    或如下(当使用 --cc 选项时):

    diff --cc file
  2. 它的后面是一个或多个扩展头信息行(本例显示的是与两个父提交的合并):

    index <哈希>,<哈希>..<哈希>
    mode <模式>,<模式>..<模式>
    new file mode <模式>
    deleted file mode <模式>,<模式>

    The mode <mode>,<mode>..<mode> line appears only if at least one of the <mode> is different from the rest. Extended headers with information about detected contents movement (renames and copying detection) are designed to work with diff of two <tree-ish> and are not used by combined diff format.

  3. 它的后面是两行源文件/目标文件的头信息

    --- a/file
    +++ b/file

    类似于传统的 "统一" 差异格式的双行头,/dev/null 用来表示创建或删除的文件。

    但是,如果提供了 --combined-all-paths 选项,你就会得到一个 N+1 行的源文件/目标文件头,其中 N 是合并提交中的父提交数量

    --- a/file
    --- a/file
    --- a/file
    +++ b/file

    如果重命名或复制检测处于活动状态,这种扩展格式可能很有用,可以让你在不同的父提交中看到文件的原始名称。

  4. 修改了文件块头信息的格式,以防止不小心将其送入 patch -p1。合并的差异格式是为审查合并提交的修改而创建的,并不是为了应用。这个变化类似于扩展的 "索引" 头信息的变化:

    @@@ <from-file-range> <from-file-range> <to-file-range> @@@

    块中有(父提交数量+1)@ 字符,用于合并的差异格式。

与传统的 "统一" 差异格式不同,这种格式显示两个文件 A 和 B 的列,其中有 -(减号 — 在 A 中出现,但在 B 中删除),+(加号 — 在 A 中缺少,但在 B 中增加),或 " "(空格 — 不变)前缀,这种格式比较两个或多个文件与一个文件 X,并显示 X 与其中每个文件的差异。文件中的每一个都有一列被前置在输出行中,以指出 X 的行与它的不同之处。

第 N 列中的 - 字符意味着该行出现在文件 N 中,但它没有出现在结果文件中。第 N 列中的 + 字符意味着该行出现在结果文件中,而文件 N 中没有该行(换句话说,从该父提交的角度来看,该行是被添加的)。

在上面的输出示例中,两个文件中的函数签名都被改变了(因此从文件 1 和文件 2 中都有表示删除的 -,而 ++ 表示被添加的一行没有出现在文件 1 或文件 2 中)。另外还有 8 行与文件 1 中的相同,但没有出现在文件 2 中(因此前缀为 +)。

当用 git diff-tree -c 显示时,它将合并提交的父提交文件与合并结果进行比较(即文件 1 …​ 文件 N 是父提交文件)。当用 git diff-files -c 显示时,它将两个未解决的合并父提交文件与工作树文件进行比较(即文件 1 是阶段 2 ,又称 "我们的版本",文件 2 是阶段 3,又称 "他们的版本")。

EXAMPLES

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

显示所有在本地主库但不在任何远程仓库主库分支中的提交。

git log -p -m -first-parent

显示包括变化差异的历史,但只从 "主分支 "的角度,跳过来自合并分支的提交,并显示合并带来的全部变化差异。 这只有在遵循严格的政策,在停留在一个集成分支时合并所有主题分支时才有意义。

git log -L '/int main/',/^}/:main.c

显示了文件`main.c`中的函数`main()`是如何随时间演变的。

git log -3

将显示的提交数量限制在3个。

DISCUSSION

Git在某种程度上是与字符编码无关的。

  • blob对象的内容是未经解释的字节序列。 在核心层没有编码转换。

  • 路径名以UTF-8规范化形式C编码,这适用于树对象、索引文件、参考名称,以及命令行参数、环境变量和配置文件(.git/config(见git-config[1]),linkgit:gitignore[5],linkgit: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 Porcelain的设计并不强制要求项目使用UTF-8。 如果某个项目的所有参与者都认为使用传统编码更方便,Git也不会禁止。 然而,有几件事需要注意。

  1. git commit "和 "git commit-tree "如果收到的提交日志信息不像是有效的UTF-8字符串,就会发出警告,除非你明确表示你的项目使用的是传统编码。 说这个的方法是在`.git/config`文件中设置`i18n.commitEncoding`,像这样。

    [i18n]
    	commitEncoding = ISO-8859-1

    用上述设置创建的提交对象在其`encoding`头中记录了`i18n.commitEncoding`的值。 这是为了帮助以后看这些对象的人。 缺少这个头意味着提交日志信息是以UTF-8编码的。

  2. git log, git show, git blame and friends look at the encoding header of a commit object, and try to re-code the log message into UTF-8 unless otherwise specified. You can specify the desired output encoding with i18n.logOutputEncoding in .git/config file, like this:

    [i18n]
    	logOutputEncoding = ISO-8859-1

    如果你没有这个配置变量,则使用`i18n.commitEncoding`的值来代替。

请注意,我们特意选择在提交对象层面上,不对提交日志信息进行重新编码,因为重新编码为UTF-8不一定是一个可逆的操作。

配置

核心变量见 git-config[1] ,与 diff 生成相关的设置见 git-diff[1]

format.pretty

`--format`选项的默认值。 (见上面的 "漂亮的格式"。)默认为 "中等"。

i18n.logOutputEncoding

显示日志时要使用的编码。 (见上面的 "讨论"。)如果设置了,默认为`i18n.commitEncoding`的值,否则为UTF-8。

Warning

Missing zh_HANS-CN/includes/cmd-config-section-rest.txt

See original version for this content.

Warning

Missing zh_HANS-CN/config/log.txt

See original version for this content.

Warning

Missing zh_HANS-CN/config/notes.txt

See original version for this content.

GIT

属于 git[1] 文档

scroll-to-top