diff options
Diffstat (limited to 'Documentation/git-blame.txt')
-rw-r--r-- | Documentation/git-blame.txt | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/Documentation/git-blame.txt b/Documentation/git-blame.txt new file mode 100644 index 0000000000..9516914236 --- /dev/null +++ b/Documentation/git-blame.txt @@ -0,0 +1,221 @@ +git-blame(1) +============ + +NAME +---- +git-blame - Show what revision and author last modified each line of a file + +SYNOPSIS +-------- +[verse] +'git blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-e] [-p] [-w] [--incremental] [-L n,m] + [-S <revs-file>] [-M] [-C] [-C] [-C] [--since=<date>] [--abbrev=<n>] + [<rev> | --contents <file> | --reverse <rev>] [--] <file> + +DESCRIPTION +----------- + +Annotates each line in the given file with information from the revision which +last modified the line. Optionally, start annotating from the given revision. + +The command can also limit the range of lines annotated. + +The report does not tell you anything about lines which have been deleted or +replaced; you need to use a tool such as 'git diff' or the "pickaxe" +interface briefly mentioned in the following paragraph. + +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: + +----------------------------------------------------------------------------- +$ git log --pretty=oneline -S'blame_usage' +5040f17eba15504bad66b14a645bddd9b015ebb7 blame -S <ancestry-file> +ea4c7f9bf69e781dd0cd88d2bccb2bf5cc15c9a7 git-blame: Make the output +----------------------------------------------------------------------------- + +OPTIONS +------- +include::blame-options.txt[] + +-c:: + Use the same output mode as linkgit:git-annotate[1] (Default: off). + +--score-debug:: + 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 'git blame' to consider those lines + of code to have been moved. + +-f:: +--show-name:: + 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. + +-n:: +--show-number:: + Show the line number in the original commit (Default: off). + +-s:: + Suppress the author name and timestamp from the output. + +-e:: +--show-email:: + Show the author email instead of author name (Default: off). + +-w:: + Ignore whitespace when comparing the parent's version and + the child's to find where the lines came from. + +--abbrev=<n>:: + 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. + + +THE PORCELAIN FORMAT +-------------------- + +In this format, each line is output after a header; the +header at the minimum has the first line which has: + +- 40-byte SHA-1 of the commit the line is attributed to; +- the line number of the line in the original file; +- the line number of the line in the final file; +- 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. + +This header line is followed by the following information +at least once for each commit: + +- the author name ("author"), email ("author-mail"), time + ("author-time"), and timezone ("author-tz"); similarly + for committer. +- the filename in the commit that the line is attributed to. +- the first line of the commit log message ("summary"). + +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. + +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: + + # count the number of lines attributed to each author + git blame --line-porcelain file | + sed -n 's/^author //p' | + sort | uniq -c | sort -rn + + +SPECIFYING RANGES +----------------- + +Unlike 'git blame' and 'git annotate' 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 -- both ask for 21 lines starting at +line 40): + + git blame -L 40,60 foo + git blame -L 40,+21 foo + +Also you can use a regular expression to specify the line range: + + git blame -L '/^sub hello {/,/^}$/' foo + +which limits the annotation to the body of the `hello` subroutine. + +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 'git rev-list': + + git blame v2.6.18.. -- foo + git blame --since=3.weeks -- foo + +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. + +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: + + git log --diff-filter=A --pretty=short -- foo + +and then annotate the change between the commit and its +parents, using `commit{caret}!` notation: + + git blame -C -C -f $commit^! -- foo + + +INCREMENTAL OUTPUT +------------------ + +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. + +The output format is similar to the Porcelain format, but it +does not contain the actual lines from the file that is being +annotated. + +. Each blame entry always starts with a line of: + + <40-byte hex sha1> <sourceline> <resultline> <num_lines> ++ +Line numbers count from 1. + +. 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.). + +. Unlike the Porcelain format, the filename information is always + given and terminates the entry: + + "filename" <whitespace-quoted-filename-goes-here> ++ +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). ++ +[NOTE] +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. + + +MAPPING AUTHORS +--------------- + +include::mailmap.txt[] + + +SEE ALSO +-------- +linkgit:git-annotate[1] + +GIT +--- +Part of the linkgit:git[1] suite |