簡體中文 ▾ 主題 ▾ 最新版本 ▾ git-blame 上次更新於 2.52.0

名稱

git-blame - 顯示修改檔案中每行的提交和作者

概要

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

描述

用最後修改該行的提交資訊標註給定檔案中的每一行。可選地,可以從給定的提交開始標註。

-L 被指定一次或多次時,它將標註限制在請求的行上。

行的來源會在整個檔案重新命名時自動跟蹤(目前沒有選項可以關閉重新命名跟蹤)。要跟蹤從一個檔案移動到另一個檔案,或複製貼上到另一個檔案等的行,請參閱 -C-M 選項。

報告不會告訴你任何關於已被刪除或替換的行的資訊;你需要使用 git diff 等工具,或者在下一段中簡要提到的“pickaxe”介面。

除了支援檔案標註,Git 還支援搜尋開發歷史以查詢程式碼片段的出現。這使得跟蹤程式碼片段何時被新增到檔案、在檔案之間移動或複製、以及最終被刪除或替換成為可能。它透過在 diff 中搜索文字字串來實現。一個搜尋 blame_usage 的 pickaxe 介面的簡短示例

$ git log --pretty=oneline -S'blame_usage'
5040f17eba15504bad66b14a645bddd9b015ebb7 blame -S <ancestry-file>
ea4c7f9bf69e781dd0cd88d2bccb2bf5cc15c9a7 git-blame: Make the output

選項

-b

為邊界提交顯示空白的 SHA-1。這也可以透過 blame.blankBoundary 配置選項控制。

--root

不要將根提交視為邊界。這也可以透過 blame.showRoot 配置選項控制。

--show-stats

在 blame 輸出的末尾包含額外的統計資訊。

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

僅標註 <start>,<end> 給出的行範圍,或由函式名正則表示式 <funcname> 指定的範圍。可以多次指定。允許重疊範圍。

<start><end> 是可選的。-L <start>-L <start>,<start> 跨越到檔案末尾。-L ,<end> 從檔案開頭跨越到 <end>

<start><end> 可以採用以下形式之一

  • <number>

    如果 <start><end> 是一個數字,它指定一個絕對行號(行從 1 開始計數)。

  • /<regex>/

    此形式將使用第一個匹配給定 POSIX <regex> 的行。如果 <start> 是一個正則表示式,它將從上一個 -L 範圍的末尾(如果存在)開始搜尋,否則從檔案開頭開始搜尋。如果 <start>^/<regex>/,它將從檔案開頭開始搜尋。如果 <end> 是一個正則表示式,它將從 <start> 給定的行開始搜尋。

  • +<offset>-<offset>

    這僅對 <end> 有效,並將指定 <start> 給定行之前或之後的行數。

如果用 <start><end> 的位置給出了 :<funcname>,它是一個正則表示式,表示從第一個匹配 <funcname> 的 funcname 行到下一個 funcname 行的範圍。:<funcname> 從上一個 -L 範圍的末尾(如果存在)開始搜尋,否則從檔案開頭開始搜尋。^:<funcname> 從檔案開頭開始搜尋。函式名的確定方式與 git diff 如何處理補丁塊頭相同(參見 gitattributes[5] 中的“定義自定義塊頭”)。

-l

顯示長修訂版本(預設:關閉)。

-t

顯示原始時間戳(預設:關閉)。

-S <revs-file>

使用 revs-file 中的修訂版本,而不是呼叫 git-rev-list[1]

--reverse <rev>..<rev>

向前遍歷歷史記錄而不是向後。此選項顯示最後一次修改行的提交,而不是顯示行首次出現的提交。這需要一個修訂範圍,如 START..END,其中要標註的路徑存在於 START 中。git blame --reverse START 被視為 git blame --reverse START..HEAD 以方便使用。

--first-parent

遇到合併提交時只跟蹤第一個父提交。此選項可用於確定一行是在某個特定整合分支中引入的,而不是在整個歷史記錄中引入的。

-p
--porcelain

以適合機器消費的格式顯示。

--line-porcelain

以 porcelain 格式顯示,但輸出每行的提交資訊,而不僅僅是提交首次被引用的地方。隱含 --porcelain。

--incremental

以適合機器消費的格式增量顯示結果。

--encoding=<encoding>

指定用於輸出作者姓名和提交摘要的編碼。將其設定為 none 可使 blame 輸出未經轉換的資料。有關更多資訊,請參閱 git-log[1] 手冊頁中關於編碼的討論。

--contents <file>

使用命名檔案中的內容進行標註,如果指定了 <rev>,則從 <rev> 開始,否則從 HEAD 開始。你可以指定 - 使命令從標準輸入讀取檔案內容。

--date <format>

指定用於輸出日期的格式。如果未提供 --date,則使用 blame.date 配置變數的值。如果 blame.date 配置變數也未設定,則使用 iso 格式。支援的值請參閱 git-log[1] 中 --date 選項的討論。

--progress
--no-progress

進度狀態預設在連線到終端時透過標準錯誤流報告。即使未連線到終端,此標誌也會啟用進度報告。不能將 --progress--porcelain--incremental 一起使用。

-M[<num>]

檢測檔案內移動或複製的行。當一個提交移動或複製一行(例如,原始檔案有 A 然後 B,提交將其更改為 B 然後 A)時,傳統的 blame 演算法只識別一半的移動,通常將向上移動的行(即 B)歸因於父提交,並將向下移動的行(即 A)歸因於子提交。使用此選項,透過額外的檢查,兩組行都將歸因於父提交。

<num> 是可選的,但它是 Git 必須檢測到的字母數字字元數下限,以便將這些行與父提交關聯起來。預設值為 20。

-C[<num>]

除了 -M 之外,還檢測同一提交中修改的其他檔案的行的移動或複製。這在重組程式並跨檔案移動程式碼時很有用。當此選項給定兩次時,命令還會查詢建立檔案的提交中其他檔案的副本。當此選項給定三次時,命令還會查詢任何提交中其他檔案的副本。

<num> 是可選的,但它是 Git 必須檢測到的跨檔案移動/複製的字母數字字元數下限,以便將這些行與父提交關聯起來。預設值為 40。如果有多個 -C 選項,則最後一個 -C 的 <num> 引數將生效。

--ignore-rev <rev>

在分配 blame 時忽略由某個修訂版本所做的更改,就好像該更改從未發生過一樣。由被忽略的提交更改或新增的行將被歸因於上一提交,該提交更改了該行或附近行。此選項可以多次指定以忽略多個修訂版本。如果設定了 blame.markIgnoredLines 配置選項,則被忽略提交更改並歸因於另一提交的行將在 blame 輸出中標記為 ?。如果設定了 blame.markUnblamableLines 配置選項,則那些被忽略提交觸控但我們無法歸因於另一修訂版本的行將標記為 *。在 porcelain 模式下,我們分別在換行符上列印 ignoredunblamable

--ignore-revs-file <file>

忽略 file 中列出的修訂版本,該檔案必須與 fsck.skipList 格式相同。此選項可以重複,並且這些檔案將在處理完任何透過 blame.ignoreRevsFile 配置選項指定的 file 後處理。空檔名 "" 將清除之前處理的檔案中的修訂列表。

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

顯示原始提交中的行號(預設:關閉)。

-s

抑制輸出中的作者姓名和時間戳。

-e
--show-email

顯示作者電子郵件而不是作者姓名(預設:關閉)。這也可以透過 blame.showEmail 配置選項控制。

-w

在比較父版本和子版本以查詢行來源時忽略空格。

--abbrev=<n>

不使用預設的 7+1 位十六進位制數字作為縮寫的物件名稱,而是使用 <m>+1 位數字,其中 <m> 至少為 <n>,但要確保提交物件名稱唯一。請注意,使用 1 列用於標記邊界提交的插入符號。

預設格式

當既未指定 --porcelain 也未指定 --incremental 選項時,git blame 將輸出每行的標註資訊,包括

  • 來自提交的縮寫物件名稱;

  • 作者標識(預設是作者姓名和日期,除非指定了 -s-e);以及

  • 行號

在行內容之前。

Porcelain 格式

在此格式中,每行在頭部資訊之後輸出;頭部至少包含以下內容:

  • 行所屬提交的 40 位元組 SHA-1;

  • 行在原始檔案中的行號;

  • 行在最終檔案中的行號;

  • 在一個標誌著一組行與前一組不同的行的起始行上,顯示該組的行數。在後續行上,此欄位不存在。

此頭部行之後,至少一次會輸出以下資訊:

  • 作者姓名(“author”)、電子郵件(“author-mail”)、時間(“author-time”)和時區(“author-tz”);提交者資訊類似。

  • 行所屬提交中的檔名。

  • 提交日誌訊息的第一行(“summary”)。

實際行的內容在上述頭部資訊之後輸出,並以 TAB 作為字首。這是為了以後可以新增更多頭部元素。

Porcelain 格式通常會抑制已經見過的提交資訊。例如,被 blame 到同一個提交的兩行都會顯示,但該提交的詳細資訊只顯示一次。特定於單個行的資訊不會分組在一起,例如標記為 ignoredunblamable 的修訂版本。這更有效率,但可能需要讀取器保留更多狀態。--line-porcelain 選項可用於為每行輸出完整的提交資訊,從而實現更簡單(但效率較低)的用法,如

# count the number of lines attributed to each author
git blame --line-porcelain file |
sed -n 's/^author //p' |
sort | uniq -c | sort -rn

指定範圍

與舊版本 git 中的 git blamegit 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 選項呼叫時,命令會一邊構建一邊輸出結果。輸出通常會先處理最近提交觸及的行(即行將按亂序標註),旨在供互動式檢視器使用。

輸出格式類似於 Porcelain 格式,但它不包含被標註檔案的實際行。

  1. 每個 blame 條目始終以一行開始:

    <40-byte-hex-sha1> <sourceline> <resultline> <num-lines>

    行號從 1 開始計數。

  2. 當一個提交首次出現在流中時,它會打印出有關該提交的各種其他資訊,每行開頭都有一個單字標籤,描述了額外的提交資訊(作者、電子郵件、提交者、日期、摘要等)。

  3. 與 Porcelain 格式不同,檔名資訊始終提供,並且以檔名行結束該條目

    "filename" <whitespace-quoted-filename-goes-here>

    因此,對於某些面向行和單詞的解析器(對於大多數指令碼語言來說應該是很自然的),它非常容易解析。

    注意
    對於進行解析的人員:為了使其更健壯,只需忽略第一個和最後一個行(“<sha1>”和“filename”行)之間的所有行,其中您不識別標籤詞(或不關心該特定標籤詞)在“擴充套件資訊”行的開頭。這樣,如果將來添加了資訊(例如提交編碼或擴充套件提交評論),blame 檢視器也不會受影響。

作者對映

請參閱 gitmailmap[5]

配置

本節中以下所有內容均從 git-config[1] 文件中選擇性地包含。內容與彼處相同:

blame.blankBoundary

git-blame[1] 中,為邊界提交顯示空白的提交物件名稱。此選項預設為 false。

blame.coloring

這決定了應用於 blame 輸出的著色方案。它可以是 repeatedLineshighlightRecentnone,其中 none 是預設值。

blame.date

指定用於在 git-blame[1] 中輸出日期的格式。如果未設定,則使用 iso 格式。支援的值請參閱 git-log[1] 中 --date 選項的討論。

blame.showEmail

git-blame[1] 中顯示作者電子郵件而不是作者姓名。此選項預設為 false。

blame.showRoot

git-blame[1] 中,不要將根提交視為邊界。此選項預設為 false。

blame.ignoreRevsFile

git-blame[1] 中,忽略檔案中列出的修訂版本,每行一個未縮寫的物件名稱。忽略空格和以 # 開頭的註釋。此選項可以重複多次。空檔名將重置被忽略修訂版本的列表。此選項將在命令列選項 --ignore-revs-file 之前處理。

blame.markUnblamableLines

git-blame[1] 的輸出中,用 * 標記那些被忽略修訂版本更改且我們無法歸因於另一提交的行。

blame.markIgnoredLines

git-blame[1] 的輸出中,用 ? 標記那些被忽略修訂版本更改且我們歸因於另一提交的行。

另請參閱

GIT

Git[1] 套件的一部分