在线文档教程

git log

git-log

名称

git-log - 显示提交日志

概要

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

描述

显示提交日志。

该命令将采用适用于该git rev-list命令的选项来控制显示的内容和方式,以及适用于这些git diff-*命令的选项以控制每个提交所引发的更改的方式。

选项

--follow

继续列出除重命名之外的文件历史记录(仅适用于单个文件)。

--no-decorate --decorate=short|full|auto|no

打印出任何提交的 ref 名称。如果short被指定,ref 名称前缀refs/heads/refs/tags/并且refs/remotes/将不被打印。如果full指定,将打印完整的参考名称(包括前缀)。如果auto被指定,那么如果输出到达终端,则 ref 名称显示为如果short给定,否则不显示 ref 名称。默认选项是short

--source

打印出每个提交到达的命令行给定的 ref 名称。

--use-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>

跟踪<file>中由“<start>,<end>”(或函数名称 regex <funcname>)给出的行范围的演变。您不可以提供任何路径限制器。这目前仅限于从单一修订开始,也就是说,您可能只给出零个或一个正面修订参数。您可以多次指定此选项。

<开始>和<结束>可以采取以下形式之一:

  • 数字如果<开始>或<结束>是一个数字,它将指定一个绝对行号(行数从1开始)。

如果给出“:<funcname>”来代替<start>和<end>,它是一个正则表达式,表示从匹配<funcname>的第一个funcname行到下一个funcname行的范围。“:<funcname>”从上一个-L范围的末尾(如果有)搜索,否则从文件开头搜索。“^:<funcname>”从文件开头搜索。

<revision range>

仅显示指定修订范围内的提交。当没有指定<revision range>时,它默认为HEAD(即导致当前提交的整个历史记录)。origin..HEAD指定从当前提交(ie HEAD)可访问的所有提交,但不从origin。有关拼写<修订范围>的完整列表,请参阅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>

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

--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)。

--show-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

在查看合并提交后,只跟踪第一个父提交。当查看特定主题分支的演变时,此选项可以提供更好的概述,因为合并到主题分支往往只是适应不断更新的上游时间,并且此选项允许您忽略单独提交到你的历史通过这样的合并。不能与--bisect结合使用。

--not

颠倒^所有后续修订说明符的前缀(或缺少)的含义,直到下一个--not

--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 匹配的 ref <glob-pattern>都在命令行中列出<commit>。领导refs/,如果失踪,会自动添加前缀。如果模式没有?,*或者[,/*在结束时暗示。

--exclude=<glob-pattern>

不包括裁判匹配<glob-pattern>,未来--all,--branches,--tags,--remotes,或--glob原本考虑。这个选项排除累积模式到下一个的重复--all,--branches,--tags,--remotes,或--glob选择(其他选项或参数不清除积累的模式)。

给予不应该开始的模式refs/headsrefs/tagsrefs/remotes当应用到--branches--tags--remotes分别,他们必须开始refs/在应用于--glob--all。如果尾随/*是有意的,则必须明确给出。

--reflog

假设所有 reflog 提到的对象都在命令行中列为<commit>。

--ignore-missing

在输入中看到一个无效的对象名称时,假装没有给出错误的输入。

--bisect

假装好坏的二等分参考文献refs/bisect/bad被列出,并且仿佛它被跟随,--not并且良好的平分参考refs/bisect/good-*命令行。不能与--first-parent 结合使用。

--stdin

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

--cherry-mark

Like --cherry-pick (see below) but mark equivalent commits with = rather than omitting them, and inequivalent ones with +.

--cherry-pick

Omit any commit that introduces the same change as another commit on the “other side” when the set of commits are limited with symmetric difference.

For example, if you have two branches, A and B, a usual way to list all commits on only one side of them is with --left-right (see the example below in the description of the --left-right option). However, it shows the commits that were cherry-picked from the other branch (for example, “3rd on b” may be cherry-picked from branch A). With this option, such pairs of commits are excluded from the output.

--left-only --right-only

List only commits on the respective side of a symmetric difference, i.e. only those which would be marked < resp. > by --left-right.

For example, --cherry-pick --right-only A...B omits those commits from B which are in A or are patch-equivalent to a commit in A. In other words, this lists the + commits from git cherry A B. More precisely, --cherry-pick --right-only --no-merges gives the exact list.

--cherry

A synonym for --right-only --cherry-mark --no-merges; useful to limit the output to the commits on our side and mark those that have been applied to the other side of a forked history with git log --cherry upstream...mybranch, similar to git cherry upstream mybranch.

-g --walk-reflogs

Instead of walking the commit ancestry chain, walk reflog entries from the most recent one to older ones. When this option is used you cannot specify commits to exclude (that is, ^commit, commit1..commit2, and commit1...commit2 notations cannot be used).

With --pretty format other than oneline (for obvious reasons), this causes the output to have two extra lines of information taken from the reflog. The reflog designator in the output may be shown as ref@{Nth} (where Nth is the reverse-chronological index in the reflog) or as ref@{timestamp} (with the timestamp for that entry), depending on a few rules:

  • If the starting point is specified as ref@{Nth}, show the index format.

--merge

After a failed merge, show refs that touch files having a conflict and don’t exist on all heads to merge.

--boundary

Output excluded boundary commits. Boundary commits are prefixed with -.

History Simplification

Sometimes you are only interested in parts of the history, for example the commits modifying a particular <path>. But there are two parts of History Simplification, one part is selecting the commits and the other is how to do it, as there are various strategies to simplify the history.

The following options select the commits to be shown:

<paths>

Commits modifying the given <paths> are selected.

--simplify-by-decoration

Commits that are referred by some branch or tag are selected.

Note that extra commits can be shown to give a meaningful history.

The following options affect the way the simplification is performed:

Default mode

Simplifies the history to the simplest history explaining the final state of the tree. Simplest because it prunes some side branches if the end result is the same (i.e. merging branches with the same content)

--full-history

Same as the default mode, but does not prune some history.

--dense

Only the selected commits are shown, plus some to have a meaningful history.

--sparse

All commits in the simplified history are shown.

--simplify-merges

Additional option to --full-history to remove some needless merges from the resulting history, as there are no selected commits contributing to this merge.

--ancestry-path

When given a range of commits to display (e.g. commit1..commit2 or commit2 ^commit1), only display commits that exist directly on the ancestry chain between the commit1 and commit2, i.e. commits that are both descendants of commit1, and ancestors of commit2.

A more detailed explanation follows.

Suppose you specified foo as the <paths>. We shall call commits that modify foo !TREESAME, and the rest TREESAME. (In a diff filtered for foo, they look different and equal, respectively.)

In the following, we will always refer to the same example history to illustrate the differences between simplification settings. We assume that you are filtering for a file foo in this commit graph:

.-A---M---N---O---P---Q / / / / / / I B C D E Y \ / / / / / `-------------' X

The horizontal line of history A---Q is taken to be the first parent of each merge. The commits are:

  • I is the initial commit, in which foo exists with contents “asdf”, and a file quux exists with contents “quux”. Initial commits are compared to an empty tree, so I is !TREESAME.

rev-list walks backwards through history, including or excluding commits based on whether --full-history and/or parent rewriting (via --parents or --children) are used. The following settings are available.

Default mode

Commits are included if they are not TREESAME to any parent (though this can be changed, see --sparse below). If the commit was a merge, and it was TREESAME to one parent, follow only that parent. (Even if there are several TREESAME parents, follow only one of them.) Otherwise, follow all parents.

This results in:

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

Note how the rule to only follow the TREESAME parent, if one is available, removed B from consideration entirely. C was considered via N, but is TREESAME. Root commits are compared to an empty tree, so I is !TREESAME.

Parent/child relations are only visible with --parents, but that does not affect the commits selected in default mode, so we have shown the parent lines.

--full-history without parent rewriting

This mode differs from the default in one point: always follow all parents of a merge, even if it is TREESAME to one of them. Even if more than one side of the merge has commits that are included, this does not imply that the merge itself is! In the example, we get

I A B N D O P Q

M was excluded because it is TREESAME to both parents. E, C and B were all walked, but only B was !TREESAME, so the others do not appear.

Note that without parent rewriting, it is not really possible to talk about the parent/child relationships between the commits, so we show them disconnected.

--full-history with parent rewriting

Ordinary commits are only included if they are !TREESAME (though this can be changed, see --sparse below).

Merges are always included. However, their parent list is rewritten: Along each parent, prune away commits that are not included themselves. This results in

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

Compare to --full-history without rewriting above. Note that E was pruned away because it is TREESAME, but the parent list of P was rewritten to contain E's parent I. The same happened for C and N, and X, Y and Q.

In addition to the above settings, you can change whether TREESAME affects inclusion:

--dense

Commits that are walked are included if they are not TREESAME to any parent.

--sparse

All commits that are walked are included.

Note that without --full-history, this still simplifies merges: if one of the parents is TREESAME, we follow only that one, so the other sides of the merge are never walked.

--simplify-merges

First, build a history graph in the same way that --full-history with parent rewriting does (see above).

Then simplify each commit C to its replacement C' in the final history according to the following rules:

  • Set C' to C.

The effect of this is best shown by way of comparing to --full-history with parent rewriting. The example turns into:

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

Note the major differences in N, P, and Q over --full-history:

  • N's parent list had I removed, because it is an ancestor of the other parent M. Still, N remained because it is !TREESAME.

Finally, there is a fifth simplification mode available:

--ancestry-path

Limit the displayed commits to those directly on the ancestry chain between the “from” and “to” commits in the given commit range. I.e. only display commits that are ancestor of the “to” commit and descendants of the “from” commit.

As an example use case, consider the following commit history:

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

A regular D..M computes the set of commits that are ancestors of M, but excludes the ones that are ancestors of D. This is useful to see what happened to the history leading to M since D, in the sense that “what does M have that did not exist in D”. The result in this example would be all the commits, except A and B (and D itself, of course).

When we want to find out what commits in M are contaminated with the bug introduced by D and need fixing, however, we might want to view only the subset of D..M that are actually descendants of D, i.e. excluding C and K. This is exactly what the --ancestry-path option does. Applied to the D..M range, it results in:

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

The --simplify-by-decoration option allows you to view only the big picture of the topology of the history, by omitting commits that are not referenced by tags. Commits are marked as !TREESAME (in other words, kept after history simplification rules described above) if (1) they are referenced by tags, or (2) they change the contents of the paths given on the command line. All other commits are marked as TREESAME (subject to be simplified away).

Commit Ordering

By default, the commits are shown in reverse chronological order.

--date-order

Show no parents before all of its children are shown, but otherwise show commits in the commit timestamp order.

--author-date-order

Show no parents before all of its children are shown, but otherwise show commits in the author timestamp order.

--topo-order

Show no parents before all of its children are shown, and avoid showing commits on multiple lines of history intermixed.

For example, in a commit history like this:

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

where the numbers denote the order of commit timestamps, git rev-list and friends with --date-order show the commits in the timestamp order: 8 7 6 5 4 3 2 1.

With --topo-order, they would show 8 6 5 3 7 4 2 1 (or 8 7 4 2 6 5 3 1 some older commits are shown before newer ones in order to avoid showing the commits from two parallel development track mixed together.

--reverse

Output the commits chosen to be shown (see Commit Limiting section above) in reverse order. Cannot be combined with --walk-reflogs.

Object Traversal

These options are mostly targeted for packing of Git repositories.

--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

Overrides a previous --no-walk.

Commit Formatting

--pretty=<format> --format=<format>

Pretty-print the contents of the commit logs in a given format, where <format> can be one of oneline, short, medium, full, fuller, email, raw, format:<string> and tformat:<string>. When <format> is none of the above, and has %placeholder in it, it acts as if --pretty=tformat:<format> were given.

See the "PRETTY FORMATS" section for some additional details for each format. When =<format> part is omitted, it defaults to medium.

Note: you can specify the default pretty format in the repository configuration (see git-config[1]).

--abbrev-commit

Instead of showing the full 40-byte hexadecimal commit object name, show only a partial prefix. Non default number of digits can be specified with "--abbrev=<n>" (which also modifies diff output, if it is displayed).

This should make "--pretty=oneline" a whole lot more readable for people using 80-column terminals.

--no-abbrev-commit

Show the full 40-byte hexadecimal commit object name. This negates --abbrev-commit and those options which imply it such as "--oneline". It also overrides the log.abbrevCommit variable.

--oneline

This is a shorthand for "--pretty=oneline --abbrev-commit" used together.

--encoding=<encoding>

The commit objects record the encoding used for the log message in their encoding header; this option can be used to tell the command to re-code the commit log message in the encoding preferred by the user. For non plumbing commands this defaults to UTF-8. Note that if an object claims to be encoded in X and we are outputting in X, we will output the object verbatim; this means that invalid sequences in the original commit may be copied to the output.

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

Perform a tab expansion (replace each tab with enough spaces to fill to the next display column that is multiple of <n>) in the log message before showing it in the output. --expand-tabs is a short-hand for --expand-tabs=8, and --no-expand-tabs is a short-hand for --expand-tabs=0, which disables tab expansion.

By default, tabs are expanded in pretty formats that indent the log message by 4 spaces (i.e. medium, which is the default, full, and fuller).

--notes=<treeish>

Show the notes (see git-notes[1]) that annotate the commit, when showing the commit log message. This is the default for git log, git show and git whatchanged commands when there is no --pretty, --format, or --oneline option given on the command line.

By default, the notes shown are from the notes refs listed in the core.notesRef and notes.displayRef variables (or corresponding environment overrides). See git-config[1] for more details.

With an optional <treeish> argument, use the treeish to find the notes to display. The treeish can specify the full refname when it begins with refs/notes/; when it begins with notes/, refs/ and otherwise refs/notes/ is prefixed to form a full name of the ref.

Multiple --notes options can be combined to control which notes are being displayed. Examples: "--notes=foo" will show only notes from "refs/notes/foo"; "--notes=foo --notes" will show both notes from "refs/notes/foo" and from the default notes ref(s).

--no-notes

Do not show notes. This negates the above --notes option, by resetting the list of notes refs from which notes are shown. Options are parsed in the order given on the command line, so e.g. "--notes --notes=foo --no-notes --notes=bar" will only show notes from "refs/notes/bar".

--show-notes=<treeish> --no-standard-notes

These options are deprecated. Use the above --notes/--no-notes options instead.

--show-signature

Check the validity of a signed commit object by passing the signature to gpg --verify and show the output.

--relative-date

Synonym for --date=relative.

--date=<format>

Only takes effect for dates shown in human-readable format, such as when using --pretty. log.date config variable sets a default value for the log command’s --date option. By default, dates are shown in the original time zone (either committer’s or author’s). If -local is appended to the format (e.g., iso-local), the user’s local time zone is used instead.

--date=relative shows dates relative to the current time, e.g. “2 hours ago”. The -local option has no effect for --date=relative.

--date=local is an alias for --date=default-local.

--date=iso (or --date=iso8601) shows timestamps in a ISO 8601-like format. The differences to the strict ISO 8601 format are:

  • a space instead of the T date/time delimiter

--date=iso-strict (or --date=iso8601-strict) shows timestamps in strict ISO 8601 format.

  • --date=rfc (or --date=rfc2822) shows timestamps in RFC 2822 format, often found in email messages.

--parents

Print also the parents of the commit (in the form "commit parent…​"). Also enables parent rewriting, see History Simplification below.

--children

Print also the children of the commit (in the form "commit child…​"). Also enables parent rewriting, see History Simplification below.

--left-right

Mark which side of a symmetric difference a commit is reachable from. Commits from the left side are prefixed with < and those from the right with >. If combined with --boundary, those commits are prefixed with -.

For example, if you have this topology:

y---b---b branch B / \ / / . / / \ o---x---a---a branch A

you would get an output like this:

$ 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

Draw a text-based graphical representation of the commit history on the left hand side of the output. This may cause extra lines to be printed in between commits, in order for the graph history to be drawn properly. Cannot be combined with --no-walk.

This enables parent rewriting, see History Simplification below.

This implies the --topo-order option by default, but the --date-order option may also be specified.

--show-linear-break=<barrier>

When --graph is not used, all history branches are flattened which can make it hard to see that the two consecutive commits do not belong to a linear branch. This option puts a barrier in between them in that case. If <barrier> is specified, it is the string that will be shown instead of the default one.

Diff Formatting

Listed below are options that control the formatting of diff output. Some of them are specific to git-rev-list[1], however other diff options may be given. See git-diff-files[1] for more options.

-c

With this option, diff output for a merge commit shows the differences from each of the parents to the merge result simultaneously instead of showing pairwise diff between a parent and the result one at a time. Furthermore, it lists only files which were modified from all parents.

--cc

This flag implies the -c option and further compresses the patch output by omitting uninteresting hunks whose contents in the parents have only two variants and the merge result picks one of them without modification.

-m

This flag makes the merge commits show the full diff like regular commits; for each merge parent, a separate log entry and diff is generated. An exception is that only diff against the first parent is shown when --first-parent option is given; in that case, the output represents the changes the merge brought into the then-current branch.

-r

Show recursive diffs.

-t

Show the tree objects in the diff output. This implies -r.

Pretty formats

If the commit is a merge, and if the pretty-format is not oneline, email or raw, an additional line is inserted before the Author: line. This line begins with "Merge: " and the sha1s of ancestral commits are printed, separated by spaces. Note that the listed commits may not necessarily be the list of the direct parent commits if you have limited your view of history: for example, if you are only interested in changes related to a certain directory or file.

There are several built-in formats, and you can define additional formats by setting a pretty.<name> config option to either another format name, or a format: string, as described below (see git-config[1]). Here are the details of the built-in formats:

  • oneline <sha1> <title line>

This is designed to be as compact as possible.

  • short commit <sha1> Author: <author>

<title line>

  • medium commit <sha1> Author: <author> Date: <author date>

<title line>

<full commit message>

  • full commit <sha1> Author: <author> Commit: <committer>

<title line>

<full commit message>

  • fuller commit <sha1> Author: <author> AuthorDate: <author date> Commit: <committer> CommitDate: <committer date>

<title line>

<full commit message>

  • email From <sha1> <date> From: <author> Date: <author date> Subject: PATCH <title line>

<full commit message>

  • raw The raw format shows the entire commit exactly as stored in the commit object. Notably, the SHA-1s are displayed in full, regardless of whether --abbrev or --no-abbrev are used, and parents information show the true parent commits, without taking grafts or history simplification into account. Note that this format affects the way commits are displayed, but not the way the diff is shown e.g. with git log --raw. To get full object names in a raw diff format, use --no-abbrev.

The placeholders are:

- `%H`: commit hash

- `%h`: abbreviated commit hash

- `%T`: tree hash

- `%t`: abbreviated tree hash

- `%P`: parent hashes

- `%p`: abbreviated parent hashes

- `%an`: author name

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

- `%ae`: author email

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

- `%ad`: author date (format respects --date= option)

- `%aD`: author date, RFC2822 style

- `%ar`: author date, relative

- `%at`: author date, UNIX timestamp

- `%ai`: author date, ISO 8601-like format

- `%aI`: author date, strict ISO 8601 format

- `%cn`: committer name

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

- `%ce`: committer email

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

- `%cd`: committer date (format respects --date= option)

- `%cD`: committer date, RFC2822 style

- `%cr`: committer date, relative

- `%ct`: committer date, UNIX timestamp

- `%ci`: committer date, ISO 8601-like format

- `%cI`: committer date, strict ISO 8601 format

- `%d`: ref names, like the --decorate option of [git-log[1]](git-log)

- `%D`: ref names without the " (", ")" wrapping.

- `%e`: encoding

- `%s`: subject

- `%f`: sanitized subject line, suitable for a filename

- `%b`: body

- `%B`: raw body (unwrapped subject and body)

- `%N`: commit notes

- `%GG`: raw verification message from GPG for a signed commit

- `%G?`: show "G" for a good (valid) signature, "B" for a bad signature, "U" for a good signature with unknown validity, "X" for a good signature that has expired, "Y" for a good signature made by an expired key, "R" for a good signature made by a revoked key, "E" if the signature cannot be checked (e.g. missing key) and "N" for no signature

- `%GS`: show the name of the signer for a signed commit

- `%GK`: show the key used to sign a signed commit

- `%gD`: reflog selector, e.g., `refs/stash@{1}` or `refs/stash@{2 minutes ago`}; the format follows the rules described for the `-g` option. The portion before the `@` is the refname as given on the command line (so `git log -g refs/heads/master` would yield `refs/heads/master@{0}`).

- `%gd`: shortened reflog selector; same as `%gD`, but the refname portion is shortened for human readability (so `refs/heads/master` becomes just `master`).

- `%gn`: reflog identity name

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

- `%ge`: reflog identity email

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

- `%gs`: reflog subject

- `%Cred`: switch color to red

- `%Cgreen`: switch color to green

- `%Cblue`: switch color to blue

- `%Creset`: reset color

- `%C(…​)`: color specification, as described under Values in the "CONFIGURATION FILE" section of [git-config[1]](git-config). By default, colors are shown only when enabled for log output (by `color.diff`, `color.ui`, or `--color`, and respecting the `auto` settings of the former if we are going to a terminal). `%C(auto,...)` is accepted as a historical synonym for the default (e.g., `%C(auto,red)`). Specifying `%C(always,...) will show the colors even when color is not otherwise enabled (though consider just using &grave;--color=always` to enable color for the whole output, including this format and anything else git might color). `auto` alone (i.e. `%C(auto)`) will turn on auto coloring on the next placeholders until the color is switched again.

- `%m`: left (`<`), right (`>`) or boundary (`-`) mark

- `%n`: newline

- `%%`: a raw `%`

- `%x00`: print a byte from a hex code

- `%w([<w>[,<i1>[,<i2>]]])`: switch line wrapping, like the -w option of [git-shortlog[1]](git-shortlog).

- `%<(<N>[,trunc|ltrunc|mtrunc])`: make the next placeholder take at least N columns, padding spaces on the right if necessary. Optionally truncate at the beginning (ltrunc), the middle (mtrunc) or the end (trunc) if the output is longer than N columns. Note that truncating only works correctly with N >= 2.

- `%<|(<N>)`: make the next placeholder take at least until Nth columns, padding spaces on the right if necessary

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

- `%>>(<N>)`, `%>>|(<N>)`: similar to `%>(<N>)`, `%>|(<N>)` respectively, except that if the next placeholder takes more spaces than given and there are spaces on its left, use those spaces

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

- %(trailers): display the trailers of the body as interpreted by [git-interpret-trailers[1]](git-interpret-trailers)

NoteSome placeholders may depend on other options given to the revision traversal engine. For example, the %g* reflog options will insert an empty string unless we are traversing reflog entries (e.g., by git log -g). The %d and %D placeholders will use the "short" decoration format if --decorate was not already provided on the command line.

If you add a + (plus sign) after % of a placeholder, a line-feed is inserted immediately before the expansion if and only if the placeholder expands to a non-empty string.

If you add a - (minus sign) after % of a placeholder, all consecutive line-feeds immediately preceding the expansion are deleted if and only if the placeholder expands to an empty string.

If you add a (space) after % of a placeholder, a space is inserted immediately before the expansion if and only if the placeholder expands to a non-empty string.

  • tformat: The tformat: format works exactly like format:, except that it provides "terminator" semantics instead of "separator" semantics. In other words, each commit has the message terminator character (usually a newline) appended, rather than a separator placed between entries. This means that the final entry of a single-line format will be properly terminated with a new line, just as the "oneline" format does. For example: $ 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

In addition, any unrecognized string that has a % in it is interpreted as if it has tformat: in front of it. For example, these two are equivalent:

$ git log -2 --pretty=tformat:%h 4da45bef $ git log -2 --pretty=%h 4da45bef

Common diff options

-p -u --patch

Generate patch (see section on generating patches).

-s --no-patch

Suppress diff output. Useful for commands like git show that show the patch by default, or to cancel the effect of --patch.

-U<n> --unified=<n>

Generate diffs with <n> lines of context instead of the usual three. Implies -p.

--raw

For each commit, show a summary of changes using the raw diff format. See the "RAW OUTPUT FORMAT" section of git-diff[1]. This is different from showing the log itself in raw format, which you can achieve with --format=raw.

--patch-with-raw

Synonym for -p --raw.

--indent-heuristic --no-indent-heuristic

These are to help debugging and tuning experimental heuristics (which are off by default) that shift diff hunk boundaries to make patches easier to read.

--minimal

Spend extra time to make sure the smallest possible diff is produced.

--patience

Generate a diff using the "patience diff" algorithm.

--histogram

Generate a diff using the "histogram diff" algorithm.

--diff-algorithm={patience|minimal|histogram|myers}

Choose a diff algorithm. The variants are as follows:

default, myers

The basic greedy diff algorithm. Currently, this is the default.

minimal

Spend extra time to make sure the smallest possible diff is produced.

patience

Use "patience diff" algorithm when generating patches.

histogram

This algorithm extends the patience algorithm to "support low-occurrence common elements".

For instance, if you configured diff.algorithm variable to a non-default value and want to use the default one, then you have to use --diff-algorithm=default option.

--stat[=<width>[,<name-width>,<count>]]

Generate a diffstat. By default, as much space as necessary will be used for the filename part, and the rest for the graph part. Maximum width defaults to terminal width, or 80 columns if not connected to a terminal, and can be overridden by <width>. The width of the filename part can be limited by giving another width <name-width> after a comma. The width of the graph part can be limited by using --stat-graph-width=<width> (affects all commands generating a stat graph) or by setting diff.statGraphWidth=<width> (does not affect git format-patch). By giving a third parameter <count>, you can limit the output to the first <count> lines, followed by ... if there are more.

These parameters can also be set individually with --stat-width=<width>, --stat-name-width=<name-width> and --stat-count=<count>.

--numstat

Similar to --stat, but shows number of added and deleted lines in decimal notation and pathname without abbreviation, to make it more machine friendly. For binary files, outputs two - instead of saying 0 0.

--shortstat

Output only the last line of the --stat format containing total number of modified files, as well as number of added and deleted lines.

--dirstat=<param1,param2,…​>

Output the distribution of relative amount of changes for each sub-directory. The behavior of --dirstat can be customized by passing it a comma separated list of parameters. The defaults are controlled by the diff.dirstat configuration variable (see git-config[1]). The following parameters are available:

changes

Compute the dirstat numbers by counting the lines that have been removed from the source, or added to the destination. This ignores the amount of pure code movements within a file. In other words, rearranging lines in a file is not counted as much as other changes. This is the default behavior when no parameter is given.

lines

通过执行常规基于行的差异分析来计算 dirstat 数字,并且将移除/添加的行数相加。(对于二进制文件,取而代之的是计算64字节的块,因为二进制文件没有自然的行概念)。这是一种--dirstatchanges行为更为昂贵的行为,但它可以像其他更改一样对文件中的重新排列的行进行计数。结果输出与您从其他--*stat选项中获得的结果一致。

files

通过计算更改的文件数量来计算 dirstat 数字。dirstat 分析中每个更改的文件都相同。这是计算上最便宜的--dirstat行为,因为它根本不需要查看文件内容。

cumulative

计数父目录的子目录中的更改。请注意,使用时cumulative,报告的百分比总和可能超过100%。默认(非累积)行为可以用noncumulative参数指定。

<limit>

整数参数指定截断百分比(默认为3%)。输出中不显示贡献小于此百分比的目录。

示例:以下内容将计数已更改的文件,同时忽略占已更改文件总数少于10%的目录,并累积父目录中的子目录计数:--dirstat=files,10,cumulative

--summary

输出扩展头信息的精简摘要,如创建,重命名和模式更改。

--patch-with-stat

-p --stat的同义词。

-z

用多个 NUL 分开提交,而不用新的换行符。

此外,当--raw--numstat已经给出,请勿使用路径名并将 NUL 用作输出字段终止符。

如果没有这个选项,带有“不寻常”字符的路径名将按照配置变量的说明引用core.quotePath(请参阅 git-config [1])。

--name-only

仅显示已更改文件的名称。

--name-status

仅显示已更改文件的名称和状态。有关--diff-filter状态字母的含义,请参阅选项说明。

--submodule=<format>

指定如何显示子模块中的差异。指定使用--submodule=shortshort格式时。这种格式只显示范围开始和结束处的提交名称。当--submodule或者--submodule=log被指定时,使用log格式。这种格式列出了像 git-submodule [1] summary那样的提交。当--submodule=diff指定时,使用diff格式。这种格式显示了提交范围内子模块内容变化的内联比较。如果配置选项未设置,则默认为diff.submoduleshort格式。

--color=<when>

显示有色差异。--color(即没有=<when>)是一样的--color=always。<when>可以是一个always,never或auto。

--no-color

关闭有色差异。它和--color=never一样。

--word-diff=<mode>

显示一个单词 diff,使用<mode>分隔已更改的单词。默认情况下,单词由空格分隔; 见--word-diff-regex下文。<mode>默认为plain,并且必须是以下之一:

color

仅使用颜色突出显示更改的词。意味着--color

plain

将单词显示为[-removed-]{+added+}。如果输入中出现分隔符,则不会尝试跳过分隔符,因此输出可能不明确。

porcelain

使用专门用于脚本消费的基于行的格式。以通常的统一差异格式打印已添加/已删除/未更改的运行,以行开头处的+/ -/字符开始并延伸至行尾。输入中~的换行符通过它自己的一行代字符表示。

none

再次禁用字差异。

请注意,尽管第一个模式的名称,如果启用,颜色将用于突出显示所有模式中更改的部分。

--word-diff-regex=<regex>

使用<regex>来决定一个单词是什么,而不是将非空白的运行视为一个单词。也意味着--word-diff除非已经启用。

每个<regex>的非重叠匹配都被视为一个单词。为了找到差异,这些匹配之间的任何内容都被认为是空白并被忽略(!)。你可能想追|[^[:space:]]加到你的正则表达式,以确保它匹配所有非空白字符。包含换行符的匹配在换行符处被无提地截断(!)。

例如,--word-diff-regex=.将每个字符看作单词,并相应地逐个字符地显示差异。

正则表达式也可以通过 diff 驱动程序或配置选项来设置,请参阅 gitattributes [5]或 git-config [1]。明确给予它覆盖任何 diff 驱动程序或配置设置。差异驱动程序覆盖配置设置

--color-words=<regex>

相当于--word-diff=color加(如果指定了正则表达式)--word-diff-regex=<regex>。

--no-renames

关闭重命名检测,即使配置文件提供了默认设置。

--check

警告如果更改引入冲突标记或空白错误。认为空白错误是由core.whitespace配置控制的。默认情况下,尾随空格(包括单独由空格组成的行)和空格字符(紧跟该行的初始缩进内的制表符后面的空格字符)将被视为空白错误。如果发现问题,则退出非零状态。与--exit-code 不兼容。

--ws-error-highlight=<kind>

突出显示空白的错误contextold或者new把差异线。多个值以逗号分隔,none重置以前的值,default将列表重置为newall简写为old,new,context。如果未给出此选项,并且diff.wsErrorHighlight未设置配置变量,则只会new突出显示行中的空白错误。空白错误是彩色的color.diff.whitespace

--full-index

在生成补丁格式输出时,在“索引”行上显示完整的映像前和映像后blob对象名称,而不是第一批字符。

--binary

除了--full-index,输出可以应用git-apply的二进制差异。

--abbrev=<n>

不是在 diff-raw 格式输出和 diff-tree 标题行中显示完整的40字节十六进制对象名称,只显示部分前缀。这与--full-index上面的选项无关,后者控制 diff-patch 输出格式。非默认的位数可以用指定--abbrev=<n>。

-B<n> --break-rewrites[=<n>]

将完全重写更改分解为删除和创建对。这有两个目的:

它影响到一种改变的方式,这种改变相当于整个文件的重写,而不是像一系列删除和插入混合在一起,只有几行文本与上下文相匹配,但是作为一个单一的删除旧的一切,随后是一个单次插入所有新事物,并且数字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

省略原图像进行删除,即仅打印标题,但不打印原像和之间的差异/dev/null。由此产生的补丁不适用于patchgit apply; 这仅适用于那些想专注于更改后查看文本的人。另外,输出显然缺乏足够的信息来反向应用这样的补丁,即使是手动补丁也是如此,因此也就是选项的名称。

在与-B删除/创建对的删除部分一起使用时,还要省略原图。

-l<num>

-M-C选项需要为O(n ^ 2)的处理时间,其中n是/复制目标潜在的重命名的数目。如果重命名/复制目标的数量超过指定的数量,则此选项可防止重命名/复制检测运行。

--diff-filter=[(A|C|D|M|R|T|U|X|B)…​*]

选择仅添加(A),复制(C),删除(D),修改(M),重命名(R),其类型(即常规文件,符号链接,子模块,...)更改(T),Unmerged(U),未知(X)或已配对 Broken(B)。可以使用任何过滤字符的组合(包括无)。当*(全部或无)添加到组合中时,如果有任何文件与比较中的其他条件匹配,则选择所有路径; 如果没有与其他标准匹配的文件,则不会选择任何内容。

此外,这些大写字母可以降低排除。例如--diff-filter=ad排除添加和删除的路径。

-S<string>

查找改变文件中指定字符串出现次数(即添加/删除)的差异。旨在供剧本使用。

当你寻找一个精确的代码块(比如一个结构体)并且想知道该块自第一次出现以来的历史记录时,它非常有用:迭代地使用该特征将原始图像中的有趣块返回到-S,并继续前进,直到获得该块的第一个版本。

-G<regex>

寻找补丁文本包含与<regex>匹配的添加/删除行的差异。

为了说明之间的区别-S<regex> --pickaxe-regex和-G<regex>,考虑在同一个文件中的以下DIFF提交:

+ return !regexec(regexp, two->ptr, 1, &regmatch, 0 ... - hit = !regexec(regexp, mf2.ptr, 1, &regmatch, 0

虽然git log -G"regexec\(regexp"会显示此提交,但git log -S"regexec\(regexp" --pickaxe-regex不会(因为该字符串的出现次数没有改变)。

有关pickaxe更多信息,请参阅 gitdiffcore [7]中的条目。

--pickaxe-all

当-S或-G发现更改时,显示该更改集中的所有更改,而不仅仅是包含<string>中的更改的文件。

--pickaxe-regex

将给定的<string> -S视为扩展的POSIX正则表达式进行匹配。

-O<orderfile>

控制文件在输出中出现的顺序。这覆盖了diff.orderFile配置变量(请参阅git-config [1])。取消diff.orderFile,使用-O/dev/null

输出顺序由<orderfile>中的全局模式顺序决定。所有具有与第一个模式相匹配的路径名的文件将首先输出,接下来将输出所有具有匹配第二个模式(但不是第一个)的路径名的文件,依此类推。最后输出所有不匹配任何模式的路径名的文件,就好像文件末尾有一个隐含的匹配模式一样。如果多个路径名具有相同的排名(它们匹配相同的模式但没有更早的模式),则它们的输出顺序相对于彼此是正常顺序。

按以下方式解析<orderfile>:

  • 空白行被忽略,所以它们可以用作分隔符以提高可读性。

模式与没有 FNM_PATHNAME 标志的 fnmantch(3)使用的模式具有相同的语法和语义,但如果删除任何数量的最终路径名组件都与模式匹配,则路径名也与模式匹配。例如,模式“ foo*bar”匹配“ fooasdfbar”和“ foo/bar/baz/asdf”但不是“ foobarx”。

-R

交换两个输入; 即显示索引或磁盘文件与树内容的差异。

--relative=<path>

当从项目的子目录运行时,可以通过该选项告知排除目录外的更改并显示与其相关的路径名。如果不在子目录中(例如,在裸存储库中),可以通过给出<path>作为参数来命名将哪个子目录作为输出的相对位置。

-a --text

将所有文件视为文本。

--ignore-space-at-eol

忽略 EOL 中的空白变化。

-b --ignore-space-change

忽略空白量的变化。这会忽略行结束处的空白,并认为一个或多个空白字符的所有其他序列是等价的。

-w --ignore-all-space

比较行时忽略空格。即使一行有空白,而另一行没有空白,这也会忽略差异。

--ignore-blank-lines

忽略其行全部空白的更改。

--inter-hunk-context=<lines>

显示差异 hunk 之间的上下文,直到指定的行数,从而融合彼此接近的hunk。如果配置选项未设置,则默认为diff.interHunkContext或0。

-W --function-context

显示整个周围的变化功能。

--ext-diff

允许执行一个外部比较助手。如果你用 gitattributes [5]设置外部差异驱动程序,你需要在 git-log [1]和朋友中使用这个选项。

--no-ext-diff

禁止外部差异驱动程序。

--textconv --no-textconv

在比较二进制文件时,允许(或不允许)运行外部文本转换过滤器。有关详细信息,请参阅 gitattributes [5]。由于 textconv 过滤器通常是单向转换,因此生成的差异适合人类消费,但无法应用。出于这个原因,默认情况下,textconv 过滤器仅针对 git-diff [1]和 git-log [1]启用,但不适用于 git-format-patch [1]或 diff plumbing命令。

--ignore-submodules=<when>

忽略差异代中子模块的更改。<when>可以是“none”,“untracked”,“dirty”或“all”,这是默认设置。如果子模块包含未跟踪或已修改的文件,或者 HEAD 与超级项目中记录的提交不同,并且可用于覆盖 git-config [1]或 gitmodules [5]中的任何ignore选项设置,则使用“none” ]。当使用“未跟踪”时,如果子模块仅包含未跟踪内容(但仍然针对修改内容进行扫描),则子模块不会被认为是脏的。使用“dirty”会忽略对子模块工作树的所有更改,只会显示超级项目中存储的提交更改(这是1.7.0之前的行为)。使用“全部”

--src-prefix=<prefix>

显示给定的源前缀而不是“a /”。

--dst-prefix=<prefix>

显示给定的目的地前缀而不是“b /”。

--no-prefix

不要显示任何来源或目的地前缀。

--line-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生成补丁

当使用选项运行“git-diff-index”,“git-diff-tree”或“git-diff-files”时,不带-p选项运行“git diff” --raw,使用“-p”运行“git log”选项,它们不会产生上述输出; 相反,他们生成一个补丁文件。您可以通过GIT_EXTERNAL_DIFFGIT_DIFF_OPTS环境变量自定义这些修补程序的创建。

-p选项产生的东西与传统的diff格式略有不同:

  • 它前面有一个“git diff”头文件,它看起来像这样:diff --git a / file1 b / file2

a/b/文件名是,除非重命名/副本所涉及的相同。尤其是,即使是创建或删除,/dev/null也可not用于替换文件名a/b/文件名。

当重命名/复制参与,file1file2示出了重命名/复制的源文件的名称和重命名/复制分别产生,该文件的名称。

  • 它后跟一个或多个扩展标题行:旧模式<mode>新模式<mode>已删除文件模式<mode>新文件模式<mode>从<path>复制到<path>从<path>重命名重命名为<path>相似索引<number>不相似索引<number>索引<hash> .. <hash> <mode>

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

扩展标题中的路径名称不包含a/b/前缀。

相似性指数是未改变的行的百分比,不相似性指数是改变的行的百分比。它是一个向下舍入的整数,后面跟着一个百分号。100%的相似性指数值因此被保留给两个相同的文件,而100%相异性意味着来自旧文件的行不会将其转换为新的文件。

索引行包含更改前后的 SHA-1校验和。如果文件模式没有改变,则包含<mode>; 否则,单独的行表示旧模式和新模式。

  • 带有“不常用”字符的路径名将按照配置变量的说明引用core.quotePath(请参阅 git-config [1])。

结合 diff 格式

任何 diff-generating 命令都可以使用-c--cc选项combined diff在显示合并时生成一个。这是显示与 git-diff [1]或 git-show [1]合并时的默认格式。还要注意,您可以-m选择这些命令中的任何一个来强制生成合并的单个父代的差异。

一个combined 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 - 组合文件

或者像这样(当使用--cc选项时):

diff --cc file

  • 它后面跟着一个或多个扩展标题行(此示例显示与两个父级合并):index <hash>,<hash> .. <hash> mode <mode>,<mode> .. <mode>新文件模式<mode>删除文件模式<mode>,<mode>

mode <mode>,<mode>..<mode>行仅在至少有一个<mode>与其他行不同时出现。具有关于检测到的内容移动(重命名和复制检测)的信息的扩展标头被设计为与两个<tree-ish>的差异一起工作,并且不被组合的差异格式使用。

  • 紧接着是两行文件/文件头--- a/file +++ b/file

类似于传统unified差异格式的双行标题,/dev/null用于表示创建或删除的文件。

  • 块头格式被修改以防止人们意外地将其提供给patch -p1。组合的差异格式是为了审查合并提交更改而创建的,并不适用于应用。此更改与扩展index标头中的更改类似:@@@ <from-file-range> <from-file-range> <to-file-range> @@@

组合 diff 格式的块头中有(双亲数+ 1)个@字符。

与传统的unified差异格式不同,该格式显示两个文件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 aka“我们的版本”,file2为阶段3 aka“他们的版本”)。

示例

git log --no-merges

显示整个提交历史记录,但跳过任何合并

git log v2.6.12.. include/scsi drivers/scsi

显示自版本以来v2.6.12更改include/scsidrivers/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(您拥有该来源的分支)。

git log master --not --remotes=*/master

显示本地主服务器中的所有提交,但不显示任何远程资源库主分支中的提交。

git log -p -m --first-parent

显示历史记录,包括变化差异,但仅从“主分支”角度看,跳过来自合并分支的提交,并显示由合并引入的变化的完全差异。这只有在遵循严格的合并所有主题分支的策略时才有意义。

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

显示main()文件中的main.c功能随着时间的推移如何演变。

git log -3

限制显示的提交数量为3。

讨论

Git 在某种程度上是字符编码不可知的。

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

虽然我们鼓励提交日志消息使用 UTF-8编码,但核心和 Git 瓷器(Porcelain)都设计为不强制项目使用 UTF-8。如果特定项目的所有参与者发现使用遗留编码更方便,Git 不会禁止它。但是,有几件事要牢记。

  • git commitgit commit-tree如果提交给它的提交日志消息看起来不像一个有效的 UTF-8字符串,则会发出警告,除非您明确声明您的项目使用了旧版编码。说这个的方法是在.git/config文件中有 i18n.commitencoding ,像这样:i18n commitEncoding = ISO-8859-1

使用上述设置创建的提交对象记录i18n.commitEncodingencoding标题中的值。这是为了帮助稍后看到他们的其他人。缺少这个头部意味着提交日志消息以UTF-8编码。

2. git loggit showgit blame和看起来像encoding一个提交对象的报头,并且尝试除非另有规定重新代码日志消息转换成 UTF-8。您可以i18n.logOutputEncoding.git/config文件中指定所需的输出编码,如下所示:i18n logOutputEncoding = ISO-8859-1

如果您没有此配置变量,i18n.commitEncoding则会使用该值。

请注意,在提交对象级别强制使用 UTF-8时,我们故意选择不重新编写提交日志消息,因为重新编码为 UTF-8不一定是可逆操作。

组态

关于核心变量,请参阅 git-config [1],关于 diff 生成的设置,请参阅 git-diff [1]。

format.pretty

--format选项的默认值。(请参阅上文Pretty Formats。)默认为medium

i18n.logOutputEncoding

显示日志时使用编码。(请参阅Discussion上文。)如果设置默认的值为i18n.commitEncoding,否则为 UTF-8。

log.date

人可读日期的默认格式。(比较--date选项。)默认为“默认”,这意味着要写日期Sat May 8 19:35:34 2010 -0500

log.follow

如果true,git log将作为如果--follow选项当单个<path>在给定的使用。这与--follow具有相同的限制,即它不能用于跟踪多个文件,并且在非线性历史记录上不能很好地工作。

log.showRoot

如果falsegit log和相关的命令将不会把最初的承诺作为一个大的创建事件。在git log -p输出中的任何根提交将显示没有附加差异。默认是true

log.showSignature

如果truegit log和相关命令将充当如果--show-signature选项被传递给他们。

mailmap.*

参见 git-shortlog [1]。

notes.displayRef

除了由core.notesRef或者GIT_NOTES_REF设置的缺省值之外,还引用了在用log命令系列显示提交消息时的注释。参见 git-notes [1]。

可能是一个未缩写的参考名称或 glob,可能会多次指定。对于不存在的 ref,将发出警告,但不匹配任何 ref 的 glob 默默无视。

该设置可以通过该--no-notes选项禁用,由GIT_NOTES_DISPLAY_REF环境变量覆盖并由--notes=<ref>选项覆盖。