What Is Git Blame? Uncover Code Changes

Summarize this article with:

You’re staring at a line of code that makes no sense, and you need to know who wrote it and why. That’s exactly what git blame answers.

This Git command annotates every line in a file with the author, date, and commit hash of its last change. It turns a confusing block of code into a trail you can follow back to a specific person and a specific decision.

This article breaks down how git blame works, its command syntax and flags, how it compares to git log, how platforms like GitHub and VS Code display blame data, and the common mistakes that trip developers up. You’ll also learn how .git-blame-ignore-revs keeps your blame history clean after bulk formatting changes.

What is Git Blame

maxresdefault What Is Git Blame? Uncover Code Changes

Git blame is a Git command that annotates each line of a file with the author, timestamp, and commit hash of its last modification. It answers a question every developer eventually asks: who changed this line, and when?

The command operates on a single file at a time. You run git blame filename, and Git walks through the file line by line, attaching metadata to each one.

According to Hutte research, around 40% of developers have used git blame to track changes to a specific line of code. That number feels low, honestly. Most people who work in a shared codebase end up running it at some point, even if they don’t realize what it’s called.

Git blame is part of every Git installation. No plugins, no extra setup. If you have Git on your machine, you already have blame. It ships with the core toolset alongside commands like git log, git diff, and git status.

The name is a bit aggressive. Took me a while to stop feeling weird about typing “blame” into my terminal. But the command isn’t about finger-pointing. It’s about context. You’re trying to understand the history behind a piece of code, not assign fault.

The Stack Overflow Developer Survey 2024 confirms that 94% of developers rely on Git as their primary version control system. That means git blame is available to nearly every working developer, whether they use it or not.

Why is GitHub the heart of open source?

Uncover GitHub statistics: developer community growth, repository trends, collaboration patterns, and the platform that powers modern software development.

Explore GitHub Data →

How Git Blame Output Works

maxresdefault What Is Git Blame? Uncover Code Changes

Each line of git blame output contains five pieces of information, packed into a single row. Here’s what you’re looking at:

ComponentWhat It ShowsExample
Commit hashShortened SHA-1 identifying the commit82496ea3
AuthorWho last modified this linekevzettler
TimestampDate and time of the modification2018-02-28 13:37:02
Line numberPosition in the current file1
ContentThe actual code on that line# Git Blame example

Reading Repeated Commit Hashes

When you see the same commit hash repeated across multiple consecutive lines, it means those lines were all changed in the same commit. A bulk refactor or a new function addition, usually.

This is actually the quickest way to spot large-scale changes at a glance. Ten lines all pointing to the same SHA? That was probably a single feature addition or a formatting pass.

Boundary Commits

Lines marked with a ^ prefix on the commit hash indicate boundary commits. These are lines that have existed since the very first commit in the repository.

Your mileage may vary with boundary markers depending on the repository’s age and how many times the initial files were restructured early on.

Git Blame Command Syntax and Options

maxresdefault What Is Git Blame? Uncover Code Changes

The basic syntax is straightforward:

git blame

That gives you the full annotated output for every line in the file. But the real power is in the flags. Most developers I’ve worked with only know the basic command and miss the options that actually make blame useful.

Key flags at a glance:

  • -L 10,20 limits output to lines 10 through 20
  • -e shows email addresses instead of usernames
  • -w ignores whitespace-only changes
  • -C detects lines copied from other files
  • -M detects lines moved within the same file
  • --since="2 weeks ago" filters by time range

The -w flag alone saves hours of frustration. Without it, blame attributes lines to whoever last adjusted tabs or spacing, which is almost never the person you actually care about.

Line Range Filtering with -L

This is the flag you’ll use most. Instead of scrolling through hundreds of annotated lines, you can target a specific block:

git blame -L 45,60 src/utils.js

That gives you blame output only for lines 45 through 60. You can also pass a function name if your language supports it, which is tricky to get right but incredibly useful when it works.

Atlassian’s Git documentation notes that the -L option can be specified multiple times within the same command, letting you blame several non-contiguous ranges in a single run. I’ve seen very few people do this in practice.

When to Use Git Blame

maxresdefault What Is Git Blame? Uncover Code Changes

Git blame solves a specific set of problems. It’s not a general-purpose history tool. Here’s when it’s actually the right pick.

Tracking Down a Bug’s Origin

Something broke. You know which line is causing the issue. Run blame on that line to find out who changed it last, when, and what commit introduced the change.

From there, you can read the commit message (assuming it’s a good one), check the full diff, and trace the reasoning behind the modification. This is faster than digging through git log output when you already know the exact file and line number.

Understanding Undocumented Code Decisions

Every codebase has sections where someone made a decision that looks bizarre without context. Blame helps here. A Codacy report found that 53% of developers consider code reviews a mandatory workflow step, but reviewed code still ends up confusing months later.

Running blame tells you who to ask. And the linked commit often contains notes or references to a ticket that explain the “why” behind the code.

Finding the Right Person to Ask

On large teams, blame is basically a people-finder. You see a confusing block of code, blame it, and now you know exactly who to message on Slack.

Hutte data shows 75% of developers find that peer review and pair programming help catch Git issues early. Git blame feeds directly into that collaborative loop by connecting code to the developer who wrote it.

Checking Code Freshness Before Editing

If every line in a function was last touched three years ago by someone who left the company, you’re dealing with legacy code and should proceed carefully. If the lines were modified last week, the original author is probably around and can give you context.

Blame timestamps are an underrated signal for how carefully you should approach a code refactoring effort.

Git Blame vs. Git Log

These two get confused because they both show commit history. But they answer different questions.

FeatureGit BlameGit Log
FocusLine-by-line, single fileCommit-by-commit, whole repo
ShowsWho last changed each lineSequence of changes over time
Best for“Who wrote this specific line?”“What happened to this file recently?”
ScopeCurrent file state, annotatedFull history of changes

Git blame shows you the current state of a file with last-touch attribution for each line. Git log shows the sequence of commits that changed a file over time.

When git log with the -p flag (patch mode) is more useful: when you need to see the full diff of each change rather than just who last touched each line. Blame gives you the “who” quickly but hides the progression of changes.

I usually start with blame to identify the commit, then switch to log to see the broader context around that commit. They’re complementary tools. Using one without the other gives you an incomplete picture.

The 2024 State of Git Collaboration Report from JetBrains and GitKraken, which analyzed data from over 150,000 developers, found that smaller teams tend to manage pull requests more effectively. Git blame and log together help even large teams maintain code comprehension as the codebase scales.

Git Blame in Code Editors and Platforms

Most developers don’t use git blame from the terminal anymore. Or at least, not exclusively. The GUI implementations in editors and hosting platforms have gotten good enough that the command line version feels like a power-user option.

GitLens for VS Code now has over 40 million installs, according to GitKraken. That’s a staggering adoption number for a single extension, and inline blame annotations are its most popular feature.

GitHub Blame View

GitHub provides a built-in blame view for every file in a repository. Click “Blame” in the file header, and you get a color-coded, interactive version of what the terminal outputs as plain text.

What makes GitHub’s version different:

  • Each annotation links directly to the full commit diff
  • You can click through to older versions of the blame view
  • It supports .git-blame-ignore-revs natively since 2022

For teams doing code reviews, the blame view on GitHub is often more practical than running the command locally. You can share a direct URL to a specific blame view in a pull request discussion, which saves everyone time.

IDE Integrations

VS Code with GitLens: inline blame annotations appear as faded text at the end of each line. Hover over them for full commit details. You can configure it to show author, date, commit message, or any combination.

JetBrains IDEs (IntelliJ, PyCharm, WebStorm) have a built-in annotation gutter. Right-click the gutter, select “Annotate with Git Blame,” and each line lights up with color-coded authorship info.

The big advantage of GUI blame tools over the CLI is that they link directly to full commit diffs. In the terminal, you get a hash and have to run a separate command to see what actually changed. In an editor, it’s one click.

A solid web development IDE setup with blame integration cuts investigation time significantly. Took me forever to figure out how much time I was wasting by not using inline blame. Once you try it, going back to the terminal-only workflow feels ancient.

Limitations of Git Blame

maxresdefault What Is Git Blame? Uncover Code Changes

Git blame is useful, but it lies to you sometimes. Or more accurately, it shows you a version of the truth that can be misleading if you don’t know what to watch for.

The biggest problem? It only shows the last modification per line. Not the full history. Not who originally wrote it. Just who touched it most recently.

That distinction matters more than most people realize.

Formatting Commits Destroy Blame History

Run Prettier or Black across your entire codebase, and every line those tools touch gets attributed to a single formatting commit. The actual authors who wrote the logic? Gone from blame output.

The React repository ran into exactly this problem. Bulk Prettier commits like [compiler] Run prettier, fix snap touched thousands of lines, overwriting meaningful authorship data with cosmetic changes.

Hutte data shows that 55% of developers use pre-commit hooks to catch unintended changes before they’re committed. But even with hooks, a team-wide linting pass can still flatten blame history in one shot.

Blame Cannot Show Deleted Lines

Key limitation: git blame only annotates lines that currently exist in the file. If someone deleted important code, blame won’t tell you about it.

For deleted content, you need git log -p or git bisect to track down when and why lines were removed. Blame is strictly a “current state” tool.

Blame Data Depends on Commit Quality

A Codacy 2024 survey found that 56% of developers use standardized checklists for code reviews. But blame is only as useful as the commit messages behind it.

If your team writes commit messages like “fix stuff” or “WIP,” blame tells you who changed a line but gives you zero context about why. The command shows metadata. The value comes from how well your team documents their work.

Git Blame and .git-blame-ignore-revs

This feature fixes the formatting problem. Since Git version 2.23, you can tell blame to skip specific commits entirely, so bulk formatting changes don’t overwrite meaningful authorship data.

GitHub added native support for .git-blame-ignore-revs in 2022. GitLab followed with support in version 17.10. Both platforms now read the file automatically when rendering blame views in the browser.

How to Create and Use the File

StepCommand / ActionWhat It Does
Create fileAdd .git-blame-ignore-revs to repo rootLists commit hashes to skip
Add hashesOne full 40-character SHA per lineIdentifies formatting commits
Configure locallygit config blame.ignoreRevsFile .git-blame-ignore-revsAuto-applies on every blame run
Commit the fileVersion it alongside your codeShares ignore list with team

The file uses a simple format. Add comments with # to explain why each commit is being ignored. Future you (and your teammates) will appreciate that context.

Why This Matters for Teams Using Code Formatters

The JetBrains Python Developers Survey 2024 collected responses from over 30,000 developers. Tools like Black, Ruff, and Prettier are standard in modern software development workflows.

Every time one of these formatters runs across a full project, it creates exactly the kind of commit that breaks blame. Without .git-blame-ignore-revs, teams face a bad tradeoff: clean formatting or useful blame history. Now you get both.

The git config step is local, though. Each developer on the team has to run it on their own machine. That’s a common source of confusion, especially for newer team members who might not realize their blame output looks different from everyone else’s.

Platform Support

GitHub: automatic. Name the file .git-blame-ignore-revs, put it in the repo root, and GitHub’s blame view picks it up with zero configuration.

GitLab: supported since version 17.10 with the same file naming convention.

VS Code with GitLens: you can pass custom blame arguments in settings to include the --ignore-revs-file flag. Works well once configured, but it’s not automatic out of the box.

Common Git Blame Mistakes

maxresdefault What Is Git Blame? Uncover Code Changes

Most developers don’t misunderstand what blame does. They misunderstand what the output means. And that leads to some predictable mistakes.

Assuming the Blamed Author Wrote the Logic

This is the number one mistake. Blame shows who last modified a line, not who created it. Someone who ran a refactoring pass, adjusted indentation, or renamed a variable will show up as the “author” of lines they never really wrote.

Hutte research shows 90% of developers believe continuous learning is needed to avoid Git problems. Understanding what blame actually reports (last touch, not original authorship) is part of that.

Forgetting the -w Flag

Whitespace changes are the silent blame killer. Someone converts tabs to spaces, and suddenly every line in the file points to that one commit.

Always use git blame -w when investigating code history. The -w flag tells blame to ignore whitespace-only modifications and attribute lines to the previous meaningful change instead.

Blaming on the Wrong Branch

Git blame runs against whatever branch you currently have checked out. Line history can differ between branches because of cherry-picks, rebases, or divergent development paths.

If you’re investigating a production issue, make sure you’re blaming on the branch that’s actually deployed. Running blame on main when the bug exists on a release branch gives you the wrong answers.

Ignoring How Rebase and Squash Affect Attribution

A rebased commit gets a new SHA. A squashed merge collapses multiple commits into one, attributing all changes to whoever performed the squash.

GitHub community discussions have flagged this as a recurring pain point. When a maintainer squash-merges a PR, blame attributes the entire change to the squash commit, losing the granular history of who contributed individual pieces.

According to the 2024 State of Git Collaboration Report by JetBrains and GitKraken, smaller teams tend to manage pull requests more effectively, partly because they run into fewer of these attribution problems. Larger teams with multiple contributors per branch should be especially careful about merge strategies and how they affect blame.

FAQ on What Is Git Blame

What does git blame actually do?

Git blame annotates each line of a file with the commit hash, author name, and timestamp of the last modification. It tells you who changed a specific line and when that change happened.

Is git blame a negative thing?

The name sounds harsh, but it’s not about assigning fault. It’s a debugging and investigation tool. Most teams use it to find context behind code decisions, not to call someone out.

What is the difference between git blame and git log?

Git blame shows per-line attribution for a single file. Git log shows the sequence of commits over time across the entire repository. Blame answers “who wrote this line,” while log answers “what changed recently.”

How do I blame specific lines in a file?

Use the -L flag with a line range. Running git blame -L 10,25 filename.js limits the output to lines 10 through 25 only. This saves time on large files.

Why does git blame show the wrong author?

Blame shows the last person who modified each line. If someone ran a code formatter or adjusted whitespace, they’ll appear as the author even though they didn’t write the logic.

What is .git-blame-ignore-revs?

A file that lists commit hashes Git should skip when running blame. It’s used to filter out bulk formatting commits so blame results reflect meaningful code changes instead of cosmetic ones.

Does GitHub support git blame?

Yes. GitHub has a built-in blame view for every file in a repository. Click “Blame” in the file header to see color-coded, interactive line-by-line annotations with links to each commit.

How do I ignore whitespace changes in git blame?

Add the -w flag. Running git blame -w filename tells Git to skip whitespace-only modifications and attribute lines to the previous meaningful commit instead.

Can git blame track moved or copied lines?

Yes. The -M flag detects lines moved within the same file. The -C flag detects lines copied from other files. Combining both gives you more accurate authorship across your codebase.

Does git blame work in VS Code?

The GitLens extension adds inline blame annotations directly in the editor. It shows author, date, and commit message at the end of each line. Over 40 million installs make it the most popular Git extension for VS Code.

Conclusion

Git blame is one of those commands that seems simple until you actually need it. Then it becomes the fastest way to trace code authorship, understand commit history, and figure out who to talk to about a confusing block of logic.

But it has blind spots. Formatting commits, squashed merges, and whitespace changes can all distort the output. Knowing how to use flags like -w and -C, and setting up a .git-blame-ignore-revs` file, turns blame from a rough tool into a reliable one.

Pair it with git checkout and git revert when you need to act on what blame reveals. Use inline annotations through GitLens or the GitHub blame view for faster investigation during source control management workflows.

The better your team writes commit messages, the more useful blame becomes. Invest in that habit early.

50218a090dd169a5399b03ee399b27df17d94bb940d98ae3f8daff6c978743c5?s=250&d=mm&r=g What Is Git Blame? Uncover Code Changes
Related Posts