# git-blame
> 原文: [https://git-scm.com/docs/git-blame](https://git-scm.com/docs/git-blame)
## 名稱
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>]
[--progress] [--abbrev=<n>] [<rev> | --contents <file> | --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
```
## OPTIONS
```
-b
```
為邊界提交顯示空白SHA-1。這也可以通過`blame.blankboundary`配置選項進行控制。
```
--root
```
不要將root提交視為邊界。這也可以通過`blame.showRoot`配置選項進行控制。
```
--show-stats
```
在非責任輸出結束時包括其他統計數據。
```
-L <start>,<end>
```
```
-L :<funcname>
```
僅注釋給定的行范圍。可以多次指定。允許重疊范圍。
<開始>和< end>是可選的。 “-L< start>”或“-L< start>”跨越< start>到文件結束。 “-L,< end>”從文件開頭跨越到< end>。
<開始>和< end>可以采取以下形式之一:
* 數
如果< start>或者< end>是一個數字,它指定一個絕對行號(行數從1開始)。
* /正則表達式/
此表單將使用與給定POSIX正則表達式匹配的第一行。如果< start>是一個正則表達式,它將從前一個`-L`范圍的末尾搜索,如果有的話,否則從文件的開頭搜索。如果< start>是“^ / regex /”,它將從文件的開頭搜索。如果< end>是一個正則表達式,它將從< start>給出的行開始搜索。
* + offset或-offset
這僅適用于< end>并將在< start>給出的行之前或之后指定行數。
如果給出“:< funcname>”代替< start>和< end>,它是一個正則表達式,表示從匹配< funcname>的第一個funcname行到下一個funcname行的范圍。 “:< funcname>”從上一個`-L`范圍的末尾搜索(如果有的話),否則從文件的開頭搜索。 “^:< funcname>”從文件的開頭搜索。
```
-l
```
顯示長轉速(默認值:關閉)。
```
-t
```
顯示原始時間戳(默認值:關閉)。
```
-S <revs-file>
```
使用revs-file的修訂而不是調用 [git-rev-list [1]](https://git-scm.com/docs/git-rev-list) 。
```
--reverse <rev>..<rev>
```
走向歷史而不是落后。這不顯示出現一行的修訂,而是顯示一行存在的最后修訂版。這需要一系列的修訂,如START..END,其中指責路徑存在于START中。為方便起見,`git blame --reverse START`被視為`git blame --reverse START..HEAD`。
```
-p
```
```
--porcelain
```
以專為機器消耗而設計的格式顯示。
```
--line-porcelain
```
顯示瓷器格式,但輸出每行的提交信息,而不僅僅是第一次引用提交。意思是 - 瓷器。
```
--incremental
```
以設計用于機器消耗的格式逐步顯示結果。
```
--encoding=<encoding>
```
指定用于輸出作者姓名和提交摘要的編碼。將其設置為`none`會使非責任輸出非轉換數據。有關更多信息,請參閱 [git-log [1]](https://git-scm.com/docs/git-log) 手冊頁中有關編碼的討論。
```
--contents <file>
```
當< rev>如果未指定,該命令將從工作樹副本開始向后注釋更改。此標志使命令假裝工作樹副本具有指定文件的內容(指定`-`以使命令從標準輸入讀取)。
```
--date <format>
```
指定用于輸出日期的格式。如果未提供--date,則使用blame.date配置變量的值。如果未設置blame.date配置變量,則使用iso格式。有關支持的值,請參閱 [git-log [1]](https://git-scm.com/docs/git-log) 中--date選項的討論。
```
--[no-]progress
```
默認情況下,當連接到終端時,會在標準錯誤流上報告進度狀態。即使沒有附加到終端,該標志也可以進行進度報告。不能將`--progress`與`--porcelain`或`--incremental`一起使用。
```
-M[<num>]
```
檢測文件中移動或復制的行。當提交移動或復制一行行(例如原始文件有A然后是B,并且提交將其更改為B然后A)時,傳統的_指責_算法僅注意到一半的移動和通常會將向上移動(即B)的行歸咎于父級,并將責任歸咎于向下移動(即A)到子提交的行。使用此選項,兩組行都通過運行額外的檢查通道歸咎于父組。
< NUM>是可選的,但它是字母數字字符數的下限,Git必須在文件中檢測為移動/復制,以便將這些行與父提交相關聯。默認值為20。
```
-C[<num>]
```
除`-M`外,檢測從同一提交中修改的其他文件移動或復制的行。當您重新組織程序并跨文件移動代碼時,這非常有用。當此選項被給出兩次時,該命令還會在創建文件的提交中查找其他文件的副本。當此選項被給出三次時,該命令還會在任何提交中查找來自其他文件的副本。
< NUM>是可選的,但它是字母數字字符數的下限,Git必須檢測它們在文件之間移動/復制,以便將這些行與父提交相關聯。并且默認值為40.如果給出多個`-C`選項,則< num>最后一個`-C`的參數將生效。
```
-h
```
顯示幫助信息。
```
-c
```
使用與 [git-annotate [1]](https://git-scm.com/docs/git-annotate) 相同的輸出模式(默認值:關閉)。
```
--score-debug
```
包括與文件之間的行移動相關的調試信息(參見`-C`)和文件中移動的行(參見`-M`)。列出的第一個數字是分數。這是檢測為在文件之間或文件內移動的字母數字字符數。這必須高于 _git blame_ 的某個閾值才能考慮那些代碼行被移動。
```
-f
```
```
--show-name
```
在原始提交中顯示文件名。默認情況下,如果由于重命名檢測而存在來自具有不同名稱的文件的任何行,則會顯示文件名。
```
-n
```
```
--show-number
```
顯示原始提交中的行號(默認值:關閉)。
```
-s
```
從輸出中抑制作者姓名和時間戳。
```
-e
```
```
--show-email
```
顯示作者電子郵件而不是作者姓名(默認值:關閉)。這也可以通過`blame.showEmail`配置選項進行控制。
```
-w
```
在比較父版本和子版本時忽略空格以查找行的來源。
```
--abbrev=<n>
```
不使用默認的7 + 1十六進制數字作為縮寫對象名稱,而是使用< n> +1位數。請注意,1列用于標記邊界提交的插入符號。
## 瓷器格式
在這種格式中,每一行都在標題之后輸出;最小的標題有第一行有:
* 該行所屬的提交的40字節SHA-1;
* 原始文件中行的行號;
* 最終文件中行的行號;
* 在一行中,該行從與前一個提交不同的提交開始一組行,即該組中的行數。在后續行中,該字段不存在。
對于每個提交,此標題行后面至少跟隨以下信息一次:
* 作者姓名(“作者”),電子郵件(“作者郵件”),時間(“作者時間”)和時區(“author-tz”);類似的提交者。
* 提交行中的文件名。
* 提交日志消息的第一行(“摘要”)。
在上面的標題之后輸出實際行的內容,以TAB為前綴。這是為了允許稍后添加更多標題元素。
瓷器格式通常會抑制已經看到的提交信息。例如,將顯示歸咎于同一提交的兩行,但該提交的詳細信息將僅顯示一次。這樣更有效,但可能需要讀者保留更多狀態。 `--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 blame_ 和 _git注釋_不同,注釋的范圍可以限制為行范圍和修訂范圍。可以多次指定`-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. 每個責備條目始終以以下行開頭:
```
<40-byte hex sha1> <sourceline> <resultline> <num_lines>
```
行號從1開始計算。
2. 第一次提交顯示在流中時,它有各種其他有關它的信息,在每行的開頭打印出一個單詞標記,描述額外的提交信息(作者,電子郵件,提交者,日期,摘要等) )。
3. 與Porcelain格式不同,始終給出文件名信息并終止條目:
```
"filename" <whitespace-quoted-filename-goes-here>
```
因此,解析一些面向字和字的解析器(對于大多數腳本語言來說應該很自然)非常容易。
| 注意 | 對于進行解析的人:為了使其更加健壯,只需忽略第一個和最后一個(“< sha1>”和“filename”行)之間的任何行,在這些行中您無法識別標記詞(或關注那個特定的詞) )在“擴展信息”行的開頭。這樣,如果有添加的信息(如提交編碼或擴展提交注釋),責備查看器將無關緊要。 |
## 映射作者
如果文件`.mailmap`存在于存儲庫的頂層,或者位于mailmap.file或mailmap.blob配置選項所指向的位置,則它用于將作者和提交者名稱以及電子郵件地址映射到規范的真實姓名和電子郵件地址。
在簡單形式中,文件中的每一行都包含作者的規范實名,空格和提交中使用的電子郵件地址(由_<_ 和_>_ 括起來)映射到名稱。例如:
```
Proper Name <commit@email.xx>
```
更復雜的形式是:
```
<proper@email.xx> <commit@email.xx>
```
允許mailmap僅替換提交的電子郵件部分,并且:
```
Proper Name <proper@email.xx> <commit@email.xx>
```
它允許mailmap替換與指定的提交電子郵件地址匹配的提交的名稱和電子郵件,并且:
```
Proper Name <proper@email.xx> Commit Name <commit@email.xx>
```
它允許mailmap替換與指定的提交名稱和電子郵件地址匹配的提交的名稱和電子郵件。
示例1:您的歷史記錄包含兩位作者Jane和Joe的提交,其名稱以多種形式出現在存儲庫中:
```
Joe Developer <joe@example.com>
Joe R. Developer <joe@example.com>
Jane Doe <jane@example.com>
Jane Doe <jane@laptop.(none)>
Jane D. <jane@desktop.(none)>
```
現在假設Joe希望他的中間名最初使用,而Jane更喜歡她的姓氏完全拼寫出來。一個合適的`.mailmap`文件看起來像:
```
Jane Doe <jane@desktop.(none)>
Joe R. Developer <joe@example.com>
```
注意如何不需要`<jane@laptop.(none)>`的條目,因為該作者的真實姓名已經正確。
示例2:您的存儲庫包含以下作者的提交:
```
nick1 <bugs@company.xx>
nick2 <bugs@company.xx>
nick2 <nick2@company.xx>
santa <me@company.xx>
claus <me@company.xx>
CTO <cto@coompany.xx>
```
然后你可能想要一個看起來像這樣的`.mailmap`文件:
```
<cto@company.xx> <cto@coompany.xx>
Some Dude <some@dude.xx> nick1 <bugs@company.xx>
Other Author <other@author.xx> nick2 <bugs@company.xx>
Other Author <other@author.xx> <nick2@company.xx>
Santa Claus <santa.claus@northpole.xx> <me@company.xx>
```
將哈希_#_用于自己的行或電子郵件地址之后的注釋。
## 也可以看看
[git-annotate [1]](https://git-scm.com/docs/git-annotate)
## GIT
部分 [git [1]](https://git-scm.com/docs/git) 套件
- git
- git-config
- git-help
- git-init
- git-clone
- git-add
- git-status
- git-diff
- git-commit
- git-reset
- git-rm
- git-mv
- git-branch
- git-checkout
- git-merge
- git-mergetool
- git-log
- git-stash
- git-tag
- git-worktree
- git-fetch
- git-pull
- git-push
- git-remote
- git-submodule
- git-show
- git-log
- git-shortlog
- git-describe
- git-apply
- git-cherry-pick
- git-rebase
- git-revert
- git-bisect
- git-blame
- git-grep
- gitattributes
- giteveryday
- gitglossary
- githooks
- gitignore
- gitmodules
- gitrevisions
- gittutorial
- gitworkflows
- git-am
- git-format-patch
- git-send-email
- git-request-pull
- git-svn
- git-fast-import
- git-clean
- git-gc
- git-fsck
- git-reflog
- git-filter-branch
- git-instaweb
- git-archive
- git-bundle
- git-daemon
- git-update-server-info
- git-cat-file
- git-check-ignore
- git-checkout-index
- git-commit-tree
- git-count-objects
- git-diff-index
- git-for-each-ref
- git-hash-object
- git-ls-files
- git-merge-base
- git-read-tree
- git-rev-list
- git-rev-parse
- git-show-ref
- git-symbolic-ref
- git-update-index
- git-update-ref
- git-verify-pack
- git-write-tree