LinuxCommandLibrary

git-blame

Show who modified each line of a file

TLDR

Print file with author name and commit hash on each line

$ git blame [path/to/file]
copy

Print file with author email and commit hash on each line
$ git blame [[-e|--show-email]] [path/to/file]
copy

Print file with author name and commit hash on each line at a specific commit
$ git blame [commit] [path/to/file]
copy

Print file with author name and commit hash on each line before a specific commit
$ git blame [commit]~ [path/to/file]
copy

Jump to the parent of a specific commit and track a specific text and 10 of its following lines
$ git blame -L '/[text]/',+10 [a82812aa]^ tldr.py
copy

Print author name and commit hash information for a specific line range
$ git blame -L [start_line],[end_line] [path/to/file]
copy

Ignore whitespaces and line moves
$ git blame -w -C -C -C [path/to/file]
copy

SYNOPSIS

git blame [<options>] <file> [<revision>]

PARAMETERS

<file>
    The path to the file whose history is to be analyzed.

<revision>
    An optional commit or revision to start blaming from. If omitted, defaults to HEAD.

-L <start>,<end> | -L :<funcname>
    Blame only the specified line range. This can be a numerical range (e.g., 10,20) or a function name (e.g., :my_function).

-M[<num>]
    Detect moved or copied lines within the same file. <num> specifies the minimum number of alphanumeric characters that must match for a line to be considered a copy/move.

-C[<num>]
    Detect lines moved or copied from other files in the same commit. Using -CC or -CCC extends detection to different commits or files in unrelated histories, respectively.

-p | --porcelain
    Output in a machine-readable format, providing more detailed information per line, including the original commit, author, committer, and various SHA-1s.

-s
    Suppress the author name and timestamp from the output, showing only the commit SHA-1 and the line content.

--reverse
    Walk history forward instead of backward, showing the revision that introduced a change and then tracing its future modifications. Useful for understanding how a line evolved.

-b
    Show a blank SHA-1 (0000000000000000000000000000000000000000) for the original commit of a line if it was introduced by a commit that cannot be found (e.g., due to a shallow clone).

DESCRIPTION

The git-blame command is a powerful Git utility used to display revision and author information for each line of a given file. It annotates every line with details about the commit that last modified it, including the commit hash, author's name, timestamp, and the original line number from that commit. This functionality is invaluable for understanding the history of a codebase, identifying when and by whom specific lines of code were introduced or changed. It helps in debugging, refactoring, and performing code archaeology by tracing the evolution of individual lines. git-blame can traverse backwards through the commit history, offering options to filter by line range, detect moved or copied lines, or customize the output format for machine parsing.

CAVEATS

While powerful, git-blame has limitations. It indicates who and when a line was last changed, not necessarily why. Significant refactoring or reformatting of code without actual content changes can sometimes lead to misleading blame information. It also doesn't inherently track lines across file renames perfectly without explicit options like -C. For very large files or deep histories, running git-blame without specifying a start revision or line range can be computationally intensive.

DEFAULT OUTPUT FORMAT

By default, git-blame outputs each line prefixed with the commit SHA-1, the original line number, the final line number, the author's name, the timestamp, and then the content of the line itself. For example:
^fa6b1234 (Author Name 2023-10-26 10:30:45 +0100 10) import os

The ^ indicates the initial commit for that line in the file.

PERFORMANCE CONSIDERATIONS

For better performance on large repositories or files with extensive history, consider using the -L option to narrow down the line range you are interested in. Additionally, specifying a starting <revision> can significantly reduce the amount of history git-blame needs to traverse, making the command faster.

HISTORY

The git-blame command has been a core utility in Git since its inception by Linus Torvalds in 2005. Its design was influenced by similar 'annotate' or 'blame' features found in older version control systems like CVS and SVN, which served to identify the origin of lines of code. Linus himself emphasized the importance of being able to efficiently trace the history of individual lines. The command quickly became indispensable for developers needing to understand code origins, debug issues, and manage complex codebases, evolving alongside Git's capabilities to include sophisticated options for detecting moved and copied code.

SEE ALSO

git log(1), git show(1), git diff(1), git annotate(1)

Copied to clipboard