'\" t .\" Title: git-blame .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/> .\" Date: 02/24/2014 .\" Manual: Git Manual .\" Source: Git 1.9.0 .\" Language: English .\" .TH "GIT\-BLAME" "1" "02/24/2014" "Git 1\&.9\&.0" "Git Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" git-blame \- Show what revision and author last modified each line of a file .SH "SYNOPSIS" .sp .nf \fIgit blame\fR [\-c] [\-b] [\-l] [\-\-root] [\-t] [\-f] [\-n] [\-s] [\-e] [\-p] [\-w] [\-\-incremental] [\-L <range>] [\-S <revs\-file>] [\-M] [\-C] [\-C] [\-C] [\-\-since=<date>] [\-\-abbrev=<n>] [<rev> | \-\-contents <file> | \-\-reverse <rev>] [\-\-] <file> .fi .sp .SH "DESCRIPTION" .sp Annotates each line in the given file with information from the revision which last modified the line\&. Optionally, start annotating from the given revision\&. .sp When specified one or more times, \-L restricts annotation to the requested lines\&. .sp The origin of lines is automatically followed across whole\-file renames (currently there is no option to turn the rename\-following off)\&. To follow lines moved from one file to another, or to follow lines that were copied and pasted from another file, etc\&., see the \-C and \-M options\&. .sp The report does not tell you anything about lines which have been deleted or replaced; you need to use a tool such as \fIgit diff\fR or the "pickaxe" interface briefly mentioned in the following paragraph\&. .sp Apart from supporting file annotation, Git also supports searching the development history for when a code snippet occurred in a change\&. This makes it possible to track when a code snippet was added to a file, moved or copied between files, and eventually deleted or replaced\&. It works by searching for a text string in the diff\&. A small example: .sp .if n \{\ .RS 4 .\} .nf $ git log \-\-pretty=oneline \-S\(aqblame_usage\(aq 5040f17eba15504bad66b14a645bddd9b015ebb7 blame \-S <ancestry\-file> ea4c7f9bf69e781dd0cd88d2bccb2bf5cc15c9a7 git\-blame: Make the output .fi .if n \{\ .RE .\} .sp .SH "OPTIONS" .PP \-b .RS 4 Show blank SHA\-1 for boundary commits\&. This can also be controlled via the blame\&.blankboundary config option\&. .RE .PP \-\-root .RS 4 Do not treat root commits as boundaries\&. This can also be controlled via the blame\&.showroot config option\&. .RE .PP \-\-show\-stats .RS 4 Include additional statistics at the end of blame output\&. .RE .PP \-L <start>,<end>, \-L :<regex> .RS 4 Annotate only the given line range\&. May be specified multiple times\&. Overlapping ranges are allowed\&. .sp <start> and <end> are optional\&. \(lq\-L <start>\(rq or \(lq\-L <start>,\(rq spans from <start> to end of file\&. \(lq\-L ,<end>\(rq spans from start of file to <end>\&. .sp <start> and <end> can take one of these forms: .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} number .sp If <start> or <end> is a number, it specifies an absolute line number (lines count from 1)\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} /regex/ .sp This form will use the first line matching the given POSIX regex\&. If <start> is a regex, it will search from the end of the previous \-L range, if any, otherwise from the start of file\&. If <start> is \(lq^/regex/\(rq, it will search from the start of file\&. If <end> is a regex, it will search starting at the line given by <start>\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} +offset or \-offset .sp This is only valid for <end> and will specify a number of lines before or after the line given by <start>\&. .RE .sp If \(lq:<regex>\(rq is given in place of <start> and <end>, it denotes the range from the first funcname line that matches <regex>, up to the next funcname line\&. \(lq:<regex>\(rq searches from the end of the previous \-L range, if any, otherwise from the start of file\&. \(lq^:<regex>\(rq searches from the start of file\&. .RE .PP \-l .RS 4 Show long rev (Default: off)\&. .RE .PP \-t .RS 4 Show raw timestamp (Default: off)\&. .RE .PP \-S <revs\-file> .RS 4 Use revisions from revs\-file instead of calling \fBgit-rev-list\fR(1)\&. .RE .PP \-\-reverse .RS 4 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\&. .RE .PP \-p, \-\-porcelain .RS 4 Show in a format designed for machine consumption\&. .RE .PP \-\-line\-porcelain .RS 4 Show the porcelain format, but output commit information for each line, not just the first time a commit is referenced\&. Implies \-\-porcelain\&. .RE .PP \-\-incremental .RS 4 Show the result incrementally in a format designed for machine consumption\&. .RE .PP \-\-encoding=<encoding> .RS 4 Specifies the encoding used to output author names and commit summaries\&. Setting it to none makes blame output unconverted data\&. For more information see the discussion about encoding in the \fBgit-log\fR(1) manual page\&. .RE .PP \-\-contents <file> .RS 4 When <rev> is not specified, the command annotates the changes starting backwards from the working tree copy\&. This flag makes the command pretend as if the working tree copy has the contents of the named file (specify \- to make the command read from the standard input)\&. .RE .PP \-\-date <format> .RS 4 The value is one of the following alternatives: {relative,local,default,iso,rfc,short}\&. If \-\-date is not provided, the value of the blame\&.date config variable is used\&. If the blame\&.date config variable is also not set, the iso format is used\&. For more information, See the discussion of the \-\-date option at \fBgit-log\fR(1)\&. .RE .PP \-M|<num>| .RS 4 Detect moved or copied lines within a file\&. When a commit moves or copies a block of lines (e\&.g\&. the original file has A and then B, and the commit changes it to B and then A), the traditional \fIblame\fR algorithm notices only half of the movement and typically blames the lines that were moved up (i\&.e\&. B) to the parent and assigns blame to the lines that were moved down (i\&.e\&. A) to the child commit\&. With this option, both groups of lines are blamed on the parent by running extra passes of inspection\&. .sp <num> is optional but it is the lower bound on the number of alphanumeric characters that Git must detect as moving/copying within a file for it to associate those lines with the parent commit\&. The default value is 20\&. .RE .PP \-C|<num>| .RS 4 In addition to \-M, detect lines moved or copied from other files that were modified in the same commit\&. This is useful when you reorganize your program and move code around across files\&. When this option is given twice, the command additionally looks for copies from other files in the commit that creates the file\&. When this option is given three times, the command additionally looks for copies from other files in any commit\&. .sp <num> is optional but it is the lower bound on the number of alphanumeric characters that Git must detect as moving/copying between files for it to associate those lines with the parent commit\&. And the default value is 40\&. If there are more than one \-C options given, the <num> argument of the last \-C will take effect\&. .RE .PP \-h .RS 4 Show help message\&. .RE .PP \-c .RS 4 Use the same output mode as \fBgit-annotate\fR(1) (Default: off)\&. .RE .PP \-\-score\-debug .RS 4 Include debugging information related to the movement of lines between files (see \-C) and lines moved within a file (see \-M)\&. The first number listed is the score\&. This is the number of alphanumeric characters detected as having been moved between or within files\&. This must be above a certain threshold for \fIgit blame\fR to consider those lines of code to have been moved\&. .RE .PP \-f, \-\-show\-name .RS 4 Show the filename in the original commit\&. By default the filename is shown if there is any line that came from a file with a different name, due to rename detection\&. .RE .PP \-n, \-\-show\-number .RS 4 Show the line number in the original commit (Default: off)\&. .RE .PP \-s .RS 4 Suppress the author name and timestamp from the output\&. .RE .PP \-e, \-\-show\-email .RS 4 Show the author email instead of author name (Default: off)\&. .RE .PP \-w .RS 4 Ignore whitespace when comparing the parent\(cqs version and the child\(cqs to find where the lines came from\&. .RE .PP \-\-abbrev=<n> .RS 4 Instead of using the default 7+1 hexadecimal digits as the abbreviated object name, use <n>+1 digits\&. Note that 1 column is used for a caret to mark the boundary commit\&. .RE .SH "THE PORCELAIN FORMAT" .sp In this format, each line is output after a header; the header at the minimum has the first line which has: .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} 40\-byte SHA\-1 of the commit the line is attributed to; .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} the line number of the line in the original file; .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} the line number of the line in the final file; .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} on a line that starts a group of lines from a different commit than the previous one, the number of lines in this group\&. On subsequent lines this field is absent\&. .RE .sp This header line is followed by the following information at least once for each commit: .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} the author name ("author"), email ("author\-mail"), time ("author\-time"), and time zone ("author\-tz"); similarly for committer\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} the filename in the commit that the line is attributed to\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} the first line of the commit log message ("summary")\&. .RE .sp The contents of the actual line is output after the above header, prefixed by a TAB\&. This is to allow adding more header elements later\&. .sp 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\&. 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: .sp .if n \{\ .RS 4 .\} .nf # count the number of lines attributed to each author git blame \-\-line\-porcelain file | sed \-n \(aqs/^author //p\(aq | sort | uniq \-c | sort \-rn .fi .if n \{\ .RE .\} .SH "SPECIFYING RANGES" .sp Unlike \fIgit blame\fR and \fIgit annotate\fR in older versions of git, the extent of the annotation can be limited to both line ranges and revision ranges\&. The \-L option, which limits annotation to a range of lines, may be specified multiple times\&. .sp When you are interested in finding the origin for lines 40\-60 for file foo, you can use the \-L option like so (they mean the same thing \(em both ask for 21 lines starting at line 40): .sp .if n \{\ .RS 4 .\} .nf git blame \-L 40,60 foo git blame \-L 40,+21 foo .fi .if n \{\ .RE .\} .sp Also you can use a regular expression to specify the line range: .sp .if n \{\ .RS 4 .\} .nf git blame \-L \(aq/^sub hello {/,/^}$/\(aq foo .fi .if n \{\ .RE .\} .sp which limits the annotation to the body of the hello subroutine\&. .sp When you are not interested in changes older than version v2\&.6\&.18, or changes older than 3 weeks, you can use revision range specifiers similar to \fIgit rev\-list\fR: .sp .if n \{\ .RS 4 .\} .nf git blame v2\&.6\&.18\&.\&. \-\- foo git blame \-\-since=3\&.weeks \-\- foo .fi .if n \{\ .RE .\} .sp When revision range specifiers are used to limit the annotation, lines that have not changed since the range boundary (either the commit v2\&.6\&.18 or the most recent commit that is more than 3 weeks old in the above example) are blamed for that range boundary commit\&. .sp A particularly useful way is to see if an added file has lines created by copy\-and\-paste from existing files\&. Sometimes this indicates that the developer was being sloppy and did not refactor the code properly\&. You can first find the commit that introduced the file with: .sp .if n \{\ .RS 4 .\} .nf git log \-\-diff\-filter=A \-\-pretty=short \-\- foo .fi .if n \{\ .RE .\} .sp and then annotate the change between the commit and its parents, using commit^! notation: .sp .if n \{\ .RS 4 .\} .nf git blame \-C \-C \-f $commit^! \-\- foo .fi .if n \{\ .RE .\} .SH "INCREMENTAL OUTPUT" .sp When called with \-\-incremental option, the command outputs the result as it is built\&. The output generally will talk about lines touched by more recent commits first (i\&.e\&. the lines will be annotated out of order) and is meant to be used by interactive viewers\&. .sp The output format is similar to the Porcelain format, but it does not contain the actual lines from the file that is being annotated\&. .sp .RS 4 .ie n \{\ \h'-04' 1.\h'+01'\c .\} .el \{\ .sp -1 .IP " 1." 4.2 .\} Each blame entry always starts with a line of: .sp .if n \{\ .RS 4 .\} .nf <40\-byte hex sha1> <sourceline> <resultline> <num_lines> .fi .if n \{\ .RE .\} .sp Line numbers count from 1\&. .RE .sp .RS 4 .ie n \{\ \h'-04' 2.\h'+01'\c .\} .el \{\ .sp -1 .IP " 2." 4.2 .\} The first time that a commit shows up in the stream, it has various other information about it printed out with a one\-word tag at the beginning of each line describing the extra commit information (author, email, committer, dates, summary, etc\&.)\&. .RE .sp .RS 4 .ie n \{\ \h'-04' 3.\h'+01'\c .\} .el \{\ .sp -1 .IP " 3." 4.2 .\} Unlike the Porcelain format, the filename information is always given and terminates the entry: .sp .if n \{\ .RS 4 .\} .nf "filename" <whitespace\-quoted\-filename\-goes\-here> .fi .if n \{\ .RE .\} .sp and thus it is really quite easy to parse for some line\- and word\-oriented parser (which should be quite natural for most scripting languages)\&. .if n \{\ .sp .\} .RS 4 .it 1 an-trap .nr an-no-space-flag 1 .nr an-break-flag 1 .br .ps +1 \fBNote\fR .ps -1 .br For people who do parsing: to make it more robust, just ignore any lines between the first and last one ("<sha1>" and "filename" lines) where you do not recognize the tag words (or care about that particular one) at the beginning of the "extended information" lines\&. That way, if there is ever added information (like the commit encoding or extended commit commentary), a blame viewer will not care\&. .sp .5v .RE .RE .SH "MAPPING AUTHORS" .sp If the file \&.mailmap exists at the toplevel of the repository, or at the location pointed to by the mailmap\&.file or mailmap\&.blob configuration options, it is used to map author and committer names and email addresses to canonical real names and email addresses\&. .sp In the simple form, each line in the file consists of the canonical real name of an author, whitespace, and an email address used in the commit (enclosed by \fI<\fR and \fI>\fR) to map to the name\&. For example: .sp .if n \{\ .RS 4 .\} .nf Proper Name <commit@email\&.xx> .fi .if n \{\ .RE .\} .sp The more complex forms are: .sp .if n \{\ .RS 4 .\} .nf <proper@email\&.xx> <commit@email\&.xx> .fi .if n \{\ .RE .\} .sp which allows mailmap to replace only the email part of a commit, and: .sp .if n \{\ .RS 4 .\} .nf Proper Name <proper@email\&.xx> <commit@email\&.xx> .fi .if n \{\ .RE .\} .sp which allows mailmap to replace both the name and the email of a commit matching the specified commit email address, and: .sp .if n \{\ .RS 4 .\} .nf Proper Name <proper@email\&.xx> Commit Name <commit@email\&.xx> .fi .if n \{\ .RE .\} .sp which allows mailmap to replace both the name and the email of a commit matching both the specified commit name and email address\&. .sp Example 1: Your history contains commits by two authors, Jane and Joe, whose names appear in the repository under several forms: .sp .if n \{\ .RS 4 .\} .nf 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)> .fi .if n \{\ .RE .\} .sp .sp Now suppose that Joe wants his middle name initial used, and Jane prefers her family name fully spelled out\&. A proper \&.mailmap file would look like: .sp .if n \{\ .RS 4 .\} .nf Jane Doe <jane@desktop\&.(none)> Joe R\&. Developer <joe@example\&.com> .fi .if n \{\ .RE .\} .sp .sp Note how there is no need for an entry for <jane@laptop\&.(none)>, because the real name of that author is already correct\&. .sp Example 2: Your repository contains commits from the following authors: .sp .if n \{\ .RS 4 .\} .nf nick1 <bugs@company\&.xx> nick2 <bugs@company\&.xx> nick2 <nick2@company\&.xx> santa <me@company\&.xx> claus <me@company\&.xx> CTO <cto@coompany\&.xx> .fi .if n \{\ .RE .\} .sp .sp Then you might want a \&.mailmap file that looks like: .sp .if n \{\ .RS 4 .\} .nf <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> .fi .if n \{\ .RE .\} .sp .sp Use hash \fI#\fR for comments that are either on their own line, or after the email address\&. .SH "SEE ALSO" .sp \fBgit-annotate\fR(1) .SH "GIT" .sp Part of the \fBgit\fR(1) suite