git-blame.1   [plain text]


'\" t
.\"     Title: git-blame
.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
.\"      Date: 06/01/2011
.\"    Manual: Git Manual
.\"    Source: Git 1.7.5.4
.\"  Language: English
.\"
.TH "GIT\-BLAME" "1" "06/01/2011" "Git 1\&.7\&.5\&.4" "Git Manual"
.\" -----------------------------------------------------------------
.\" * 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 n,m]
            [\-S <revs\-file>] [\-M] [\-C] [\-C] [\-C] [\-\-since=<date>]
            [<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
The command can also limit the range of lines annotated\&.
.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>
.RS 4
Annotate only the given line range\&. <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 <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
.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
\-\-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, \-\-help
.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
.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 timezone ("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\&.
.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\&. 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 configuration option, 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 <\m[blue]\fBjane@laptop\fR\m[]\&\s-2\u[1]\d\s+2\&.(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
.SH "NOTES"
.IP " 1." 4
jane@laptop
.RS 4
\%mailto:jane@laptop
.RE