简体中文 ▾ Topics ▾ Latest version ▾ git-blame last updated in 2.50.0

名称

git-blame - 显示文件每一行的最后修改版本和作者

概述

git blame [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-e] [-p] [-w] [--incremental]
	    [-L <范围i>] [-S <revs-file>] [-M] [-C] [-C] [-C] [--since=<日期>]
	    [--ignore-rev <rev>] [--ignore-revs-file <文件>]
	    [--color-lines] [--color-by-age] [--progress] [--abbrev=<n>]
	    [ --contents <文件> ] [<rev> | --reverse <rev>..<rev>] [--] <文件>

描述

用最后一次修改该行的修订版的信息来注释给定文件中的每一行。可以选择从给定的修订版开始做注释。

当指定一次或多次时,-L 将注释限制在要求的行中。

在整个文件的重命名过程中,行的起源被自动跟踪(目前没有选项可以关闭重命名跟踪)。要跟踪从一个文件移到另一个文件的行,或者跟踪从另一个文件复制和粘贴的行,等等,请参见 -C-M 选项。

报告不会告诉你任何关于被删除或替换的行的信息;你需要使用一个工具,如 git diff 或下段中简要提到的 pickaxe 接口。

除了支持文件注释外,Git 还支持在开发历史中搜索代码片段何时发生变化。这使得追踪一个代码片段何时被添加到一个文件,在文件之间移动或复制,以及最终被删除或替换成为可能。它的工作原理是在差异中搜索一个文本字符串。一个搜索 blame_usage 的 pickaxe 界面的小例子:

$ git log --pretty=oneline -S'blame_usage'
5040f17eba15504bad66b14a645bddd9b015ebb7 blame -S <祖先文件>
ea4c7f9bf69e781dd0cd88d2bccb2bf5cc15c9a7 git-blame: Make the output

选项

-b

为边界提交显示空白的 SHA-1。 这也可以通过 blame.blankBoundary 配置选项来控制。

--root

不把根提交当作边界。 这也可以通过 blame.showRoot 配置选项来控制。

--show-stats

在历史追溯输出的结尾处包括额外的统计数据。

-L <start>,<end>
-L :<funcname>

仅注释由'<start>,<end>'或功能名称正则表达式'<funcname>'给出的行范围。 可以指定多次。 允许重叠范围。

<start><end> 是可选的 -L <start>-L <start>, 范围从 <start> 到文件末尾。 -L ,<end> 从文件开始到 <end>.

<开始><结束> 可以采取这些形式之一:

  • 数目

    如果'<开始>'或'<结束>'是一个数字,它指定了一个绝对行数(行数从1开始计算)。

  • /正则表达式/

    这种形式将使用与给定的 POSIX 正则表达式匹配的第一行。如果 <start> 是一个重词,它将从前一个 -L 范围的末尾开始搜索,如果有的话,则从文件的开始。 如果 <start>^/regex/,它将从文件的开始搜索。 如果 <end> 是一个正则表达式,它将从 <start> 所给的行开始搜索。

  • +offset或-offset

    这只对'<end>'有效,将指定'<start>'所给的行前或行后的数量。

如果 :<funcname> 代替了 <start><end> ,它是一个正则表达式,表示从第一个匹配 <funcname> 的 funcname 行开始,直到下一个 funcname 行的范围。:<funcname> 从上一个 -L 范围的末尾开始搜索,如果有的话,则从文件的开始搜索。^:<funcname>`从文件的开始搜索。函数名的确定方式与 `git diff 确定补丁组头的方式相同(见 gitattributes[5] 中的’定义自定义组头')。

-l

显示长转(默认值:关闭)。

-t

显示原始时间戳(默认值:关闭)。

-S <修订文件>

使用revs-file中的修订,而不是调用 git-rev-list[1]

--reverse <修订>..<修订>

Walk history forward instead of backward. Instead of showing the revision in which a line appeared, this shows the last revision in which a line has existed. This requires a range of revision like START..END where the path to blame exists in START. git blame --reverse START is taken as git blame --reverse START..HEAD for convenience.

--first-parent

在看到合并提交时只关注第一个父提交。这个选项可以用来确定某一行何时被引入某个特定的集成分支,而不是何时被引入整个历史中。

-p
--porcelain

以适合机器使用的格式显示。

--line-porcelain

显示上层命令格式,但输出每一行的提交信息,而不仅仅是第一次引用提交时的信息。 意味着 --porcelain。

--incremental

以适合机器使用的格式逐步显示结果。

--encoding=<编码>

指定用于输出作者姓名和提交摘要的编码。设置为 none 会使历史追溯输出未转换的数据。更多信息见 git-log[1] 手册页中关于编码的讨论。

--contents <文件>

使用指定文件中的内容进行注释,如果指定了 <rev>,则从 <rev> 开始,否则从 HEAD 开始。你可以指定 - 来使命令从标准输入中读取文件内容。

--date <格式>

指定用于输出日期的格式。如果没有提供 --date,则使用 blame.date 配置变量的值。如果 blame.date 配置变量也没有设置,则使用 iso 格式。关于支持的值,请参见 git-log[1] 中关于 --date 选项的讨论。

--[no-]progress

当它连接到一个终端时,默认情况下进度状态会在标准错误流中报告。这个标志可以使进度报告即使没有连接到终端。--porcelain`或--incremental` 不能与 --progress 一起使用。

-M[<数量>]

检测文件中移动或复制的行。当一次提交移动或复制一个行块时(例如,原始文件有 A,然后是 B,而提交将其改为 B,然后是 A),传统的 blame 算法只注意到一半的移动,通常将向上移动的行(即 B )归咎于父代,而将向下移动的行(即 A )归咎于子代提交。 有了这个选项,通过运行额外的检查,两组行都会被归咎于父代。

<num> 是可选的,但它是 Git 必须检测到的在文件中移动或复制的字母数字字符的数量的下限,以便它将这些行与父提交相关联。默认值是20。

-C[<数量>]

除了`-M`之外,还可以检测在同一提交中被修改的其他文件中移动或复制的行。 这在你重新组织程序并在不同文件间移动代码时很有用。 当这个选项被赋予两次时,命令会在创建文件的提交中额外寻找其他文件的拷贝。当这个选项出现三次时,命令会在任何一次提交中额外寻找其他文件的副本。

<num> 是可选的,但它是 Git 必须检测到的在文件之间移动或复制的字母数字字符的数量的下限,以便它将这些行与父提交关联起来。而默认值是 40。如果有一个以上的 -C 选项,只有最后一个 -C 的 <num> 参数起作用。

--ignore-rev <修订>

Ignore changes made by the revision when assigning blame, as if the change never happened. Lines that were changed or added by an ignored commit will be blamed on the previous commit that changed that line or nearby lines. This option may be specified multiple times to ignore more than one revision. If the blame.markIgnoredLines config option is set, then lines that were changed by an ignored commit and attributed to another commit will be marked with a ? in the blame output. If the blame.markUnblamableLines config option is set, then those lines touched by an ignored commit that we could not attribute to another revision are marked with a *. In the porcelain modes, we print ignored and unblamable on a newline respectively.

--ignore-revs-file <文件>

忽略 file 中列出的修订,其格式必须与 fsck.skipList 相同。 这个选项可以重复使用,这些文件将在任何用 blame.ignoreRevsFile 配置选项指定的文件之后被处理。 一个空的文件名,"",将清除以前处理的文件的 Revs 列表。

--color-lines

在默认格式下,如果行注释与前一行来自同一提交,则颜色不同。这可以让我们更容易区分不同提交的代码块。颜色默认为青色,可以使用 color.blame.repeatedLines 配置选项进行调整。

--color-by-age

根据默认格式的行的阶段,给行的注释着色。 color.blame.highlightRecent 配置选项控制每个阶段范围使用什么颜色。

-h

显示帮助信息。

-c

使用与 git-annotate[1] 相同的输出模式(默认:关闭)。

--score-debug

包括与文件之间行的移动(见 -C)和文件内行的移动(见 -M)有关的调试信息。 列出的第一个数字是分数。 这是检测到的在文件间或文件内移动的字母数字字符的数量。 这个数字必须超过一定的阈值,git blame 才会认为这些代码行被移动了。

-f
--show-name

显示原始提交中的文件名。 默认情况下,如果有任何一行来自不同名字的文件,由于重名检测,文件名会显示出来。

-n
--show-number

显示原始提交中的行号(默认:off)。

-s

抑制输出中的作者姓名和时间戳。

-e
--show-email

显示作者的电子邮件而不是作者的名字(默认:off)。 这也可以通过 blame.showEmail 配置选项来控制。

-w

在比较父本和子本的版本时,忽略空白,以找到行的来源。

--abbrev=<n>

不要使用默认的7+1个十六进制数字作为对象的缩写,而是使用 <m>+1 个数字,其中 <m> 至少是 <n>,但确保提交对象的名称是唯一的。 请注意,有1列是用来标记边界提交的关健词。

默认格式

当既没有指定`--porcelain` 也没有指定`--incremental` 选项时,git blame 将为每一行输出注释:

  • 该行来自的提交的缩写对象名称;

  • 作者身份(默认为作者姓名和日期,除非指定 -s-e 选项);以及

  • --line-number

在该行内容之前。

上层命令格式

在这种格式中,每一行都是在页眉之后输出的;页眉至少有第一行,它有:

  • 该行所归属的提交的 40 字节 SHA-1;

  • 原始文件中该行的行号;

  • 最后文件中该行的行号;

  • 在开始一组与前一次不同的提交的行上,该组的行数。 在随后的行中,这个字段是不存在的。

这个标题行后面是以下信息,每次提交至少有一次:

  • 作者姓名("author")、电子邮件("author-mail")、时间("author-time")和时区("author-tz");对提交者也是如此。

  • 该行归属的提交中的文件名。

  • 提交日志信息的第一行("摘要")。

实际行的内容会在上述标题之后输出,前缀为 TAB。这是为了允许以后添加更多的标题元素。

The porcelain format generally suppresses commit information that has already been seen. For example, two lines that are blamed to the same commit will both be shown, but the details for that commit will be shown only once. Information which is specific to individual lines will not be grouped together, like revs to be marked ignored or unblamable. This is more efficient, but may require more state be kept by the reader. The --line-porcelain option can be used to output full commit information for each line, allowing simpler (but less efficient) usage like:

# 统计每位作者的作品数
git blame --line-porcelain file |
sed -n 's/^author //p' |
sort | uniq -c | sort -rn

指定范围

与旧版本的 "git blame" 和 "git annotate" 不同,注释的范围可以限制在行的范围和修订范围。-L 选项将注释限制在一个行的范围内,可以多次指定。

当你对查找文件 foo 的第 40-60 行的原点感兴趣时,你可以像这样使用 -L 选项(它们的意思是一样的—​都要求从第 40 行开始的 21 行):

git blame -L 40,60 foo
git blame -L 40,+21 foo

你也可以使用正则表达式来指定行的范围:

git blame -L '/^sub hello {/,/^}$/' foo

它将注释限制在 hello 子程序的主体中。

当你对超过 v2.6.18 版本的修改不感兴趣,或者超过 3 周的修改不感兴趣时,你可以使用类似于 git rev-list 的修订范围指定器:

git blame v2.6.18.. -- foo
git blame --since=3.weeks -- foo

当修订范围指定符被用来限制注释时,自范围边界(在上面的例子中,提交 v2.6.18 或超过 3 周的最新提交)以来没有改变的行被指责为该范围边界提交。

一个特别有用的方法是看一个新增的文件是否有从现有文件中复制和粘贴的行。 有时,这表明开发人员很马虎,没有正确地重构代码。 你可以首先找到引入该文件的提交:

git log --diff-filter=A --pretty=short -- foo

然后用 commit^! 符号来注释该提交和其父辈之间的变化:

git blame -C -C -f $commit^! -- foo

增量输出

当调用 --incremental 选项时,该命令在构建过程中输出结果。 一般来说,输出结果会先谈及最近提交的行(也就是说,这些行会被不按顺序的注释),并且是为了给交互式浏览者使用。

输出格式类似于上层命令格式,但它不包含被注释的文件的实际行数。

  1. 每个历史追溯条目总是以一行字开始:

    <40-byte-hex sha1> <源行> <结果行> <数量行>

    行数从 1 开始计算。

  2. 当一个提交首次出现在数据流中时,它的各种其他信息会被打印出来,每一行的开头都有一个单字标签,描述额外的提交信息(作者、电子邮件、提交者、日期、摘要等)。

  3. 与上层命令格式不同,文件名信息总是给定的,并终止条目:

    "filename" <空白引号-片名-到此为止>

    因此,对于一些面向行和字的解析器来说,它确实很容易解析(这对于大多数脚本语言来说应该是很自然的)。

    Note
    对于做解析的人来说:为了使它更健壮,只要忽略第一和最后一个("<sha1>" 和 "filename" 行)之间的任何行,在 "扩展信息" 行的开头,你不认识标签词(或关心那个特定的)。这样一来,如果有一天增加了信息(比如提交编码或扩展的提交注释),历史追溯查看者就不会在意。

制图作者

参见 gitmailmap[5]

配置

本节中这一行以下的内容都是从 git-config[1] 文档中摘录的。其内容与那里的内容相同:

Warning

Missing zh_HANS-CN/config/blame.adoc

See original version for this content.

GIT

属于 git[1] 文档

scroll-to-top