We are thrilled to announce 📢 Kosli is now SOC 2 Type 2 compliant - Read more
✨ New Feature: Kosli Trails is live ✨ Create comprehensive audit trails for any DevOps activity - Read more
git blame

The Ultimate Guide to git blame: A How To with Examples

Bruce Johnston
Published November 22, 2022 in technology
clock icon 8 min read

Source control tools give users many powers and one of the big ones is traceability. With traceability tools you can know exactly who made each change and when they made it. In Git, you use the git blame command for this. Despite its negative-sounding name, it is a crucial command for you to know.

In this post, we’ll give you the ultimate guide on git blame. Among other things, you’ll learn the following:

  • what the command does
  • how to use it
  • how to interpret its output
  • auxiliary tools that can be of help

Let’s begin!

Does your team struggle with software audits? Is it a mess of screenshots and spreadsheets?

Learn how to automate it

Requirements

We assume you have Git installed on your machine. It’d be helpful if you knew at least a few basic commands. We don’t make any assumptions regarding your operating system and shell choice. Surprises can happen, but all the commands we’ll show should work regardless of your platform preferences.

git blame 101

Let’s start by covering some fundamental questions about the command.

What Is git blame?

git blame is a command that displays authorship information regarding the latest changes to every line in a file. Given a specific file, for each line of the file, git blame will show you the author and commit hash that modified that line most recently.

As such, git blame is an incredibly useful command regarding traceability. For instance, if you’re investigating a bug, the command lets you know which commits last touched the lines you’re looking at and who made those changes. Using git blame along with other commands, such as git diff, can significantly improve your odds of understanding the changes made to a codebase.

How Do You Use git blame?

As is the case with most commands in Git, git blame offers a lot of options. The simplest way to use it, though, is to simply execute it, followed by the path to the file you want to blame. For instance, suppose your repository contains a file called file.txt with the following content:

hello
second line

To blame the file, you’d run:

$ git blame file.txt

And the output should be something like this:

^9e49b29 (Some User 2022-10-14 19:33:45 -0300 1) hello
5fa94671 (Some User 2022-10-14 19:35:26 -0300 2) second line

The output above displays each line of the file, prefixed by the hash of the last commit that changed that line, each commit’s author, and the timestamp.

Why Is It called git blame?

“Blame” is a strong word, and often people object to it. So, why is it called that?

It seems that Git simply copied the name from its predecessors, such as Subversion, which already had a blame command. Scott Furman, a former developer at Netscape, claims to be possibly the creator of the term “blame.” In 1997, he created a utility called cvsblame, which annotated authors and revision numbers for each line of a file.

How Do I Get Out Of git blame?

By default, the result of git blame will be paginated, even if there’s not enough input for that. To quit and return to the normal shell, press q (for quit) in the terminal.

Let’s look at git blame examples

Now that you know the basics about git blame, let’s deepen your understanding of the command with some examples.

To make the git blame example feel more realistic, we’ll use a real repository from an open-source project on GitHub called AutoFixture.

So, start by cloning the project and accessing the resulting folder:

$ git clone https://github.com/AutoFixture/AutoFixture
$ cd AutoFixture

Basic git blame Example and Understanding the Output

For the first example, let’s blame a file and analyze the output:

$ git blame appveyor.yml

This is part of the result:

23faee15c (Alex Povar 2020-06-26 16:53:45 +0200  1) image: Visual Studio 2019
3dd611242 (Alex Povar 2017-04-10 21:30:33 +0300  2) 
3f644ad2e (Alex Povar 2017-04-10 12:42:06 +0300  3) environment:
3f644ad2e (Alex Povar 2017-04-10 12:42:06 +0300  4)   NUGET_API_KEY:

Here, we have four lines being annotated. As you can see, Alex Povar was the last one to touch all of the lines displayed. Lines 3 and 4 were last changed by the same commit (3f644ad2e) on April 10, 2017, at around 1 p.m. in a time zone three hours ahead of UTC. Line 2 was changed later the same day. Alex, however, modified line 1 for the last time on June 26, 2020.

git blame Example With Range of Lines

You often want to blame a file, but you’re interested in just a subset of its lines. When that’s the case, you can use the -L option to specify the desired range of lines:

$ git blame README.md -L 3,5

In the git blame example above, we target the file README.md, but specify only the lines from 3 to 5 (inclusive on both ends.) Here’s the result:

579564223 (Andrei Ivascu 2020-10-26 16:03:19 +0200 3) [![Build status](https://ci.appveyor.com/api/projects/status/qlmobf6rt05pmt7e/branch/master?svg=true)](https://ci.appveyor.com/project/AutoFixture/autofixture/branch/master)
579564223 (Andrei Ivascu 2020-10-26 16:03:19 +0200 4) [![NuGet version](https://img.shields.io/nuget/vpre/AutoFixture.svg)](https://www.nuget.org/packages/AutoFixture)
a9a1479dc (Andrei Ivascu 2021-11-09 00:34:29 +0200 5) [![MyGet (with prereleases)](https://img.shields.io/myget/autofixture/vpre/autofixture?color=blue&label=myget)](https://www.myget.org/gallery/autofixture)
(END)

Showing the Author’s Email Address

By default, git blame only shows the author’s name. If you’d rather it show the author’s email address, you can use the -e flag. Let’s combine this option with the -L option we just saw:

$ git blame README.md -L 3,5 -e

Here are the results:

579564223 (<7030530+aivascu@users.noreply.github.com> 2020-10-26 16:03:19 +0200 3) [![Build status](https://ci.appveyor.com/api/projects/status/qlmobf6rt05pmt7e/branch/master?svg=true)](https://ci.appveyor.com/project/AutoFixture/autofixture/branch/master)
579564223 (<7030530+aivascu@users.noreply.github.com> 2020-10-26 16:03:19 +0200 4) [![NuGet version](https://img.shields.io/nuget/vpre/AutoFixture.svg)](https://www.nuget.org/packages/AutoFixture)
a9a1479dc (<7030530+aivascu@users.noreply.github.com> 2021-11-09 00:34:29 +0200 5) [![MyGet (with prereleases)](https://img.shields.io/myget/autofixture/vpre/autofixture?color=blue&label=myget)](https://www.myget.org/gallery/autofixture)

Rapidly pinpoint and understand changes and events in your infrastructure and applications

Learn how

Displaying the Full Commit Hash

By default, git blame only shows the short version of commit hashes. If you want to see the full hashes, append -l (that’s a lowercase L) to the command. For instance:

$ git blame README.md -l

Blaming Across Branches

You might need to blame a file’s version from another branch (or maybe a file that only exists on that other branch!). Nothing stops you from checking that branch out using git blame on the file before going back to the original branch. 

But there’s an easier solution for that. You can use this syntax:

$ git blame <BRANCH-NAME> -- <PATH-TO-FILE>

To illustrate that, let’s quickly create and checkout a new branch:

$ git checkout -b new

Now, let’s create a new file:

$ echo hello > newfile

Time to commit the file:

$ git add .
$ git commit -m "add new file"

Now, if you go back to the original branch and try to run git blame newfile, you’ll get an error message. And that makes perfect sense, since it doesn’t exist in this branch.

However, we can easily blame across branches by running this command:

$ git blame new -- newfile

Doing that will result in the file newfile being blamed, and your name will appear as the sole editor of the file.

If that happens, it means you’ve successfully blamed across branches.

Detecting Lines Moved or Copied

git blame, by default, doesn’t take into account lines that were either copied or moved. In other words, if a line that was originally line 3 was moved to line 10, the person blamed as the author for line 10 would be the one who made the move, not the original author for line 3.

It’s possible to change this behavior by using the -M option (for lines copied or moved inside the same file) or -C (for lines from different files).

git blame and Code Editors

When developing software, it’d be nice if you could git blame without having to leave your code editor. Fortunately, this is also possible through the use of plugins.

If you use the popular Visual Studio Code (or simply VSCode) editor, you can leverage the GitLens plugin. Besides blame functionality, this plugin gives you many other interesting and useful Git-related features.

Vim is a screen-based text editor famous for (among other things) counting with a massive array of available plugins. Fugitive.vim is a plugin that makes it easier to work with Git while on Vim, and it offers git blame as a feature.

Conclusion

There are lots of good reasons for using a source control tool. One of the most important ones is traceability. With the help of Git, we can learn who made certain changes and when. 

This post was all about git blame, a super valuable and often misunderstood command. With the help of git blame, you can learn who was the last person to change each line of a given file. This knowledge can be vital, especially when you’re investigating the causes of bugs.

Like many Git commands, git blame accepts many options and arguments. In this post, we’ve covered some that allow you to: filter for a specific range of lines, change the output format to include email, replace a short commit hash with the longer version, and more.

Finally, we mentioned how plugins can make your life easier when working with a code editor, such as VSCode or Vim. We hope this guide helps you to push incredible software to your users!

Ready to go beyond git blame? Get Faster Incident Response with Change Forensics

Discover how


ABOUT THIS ARTICLE

Published November 22, 2022, in technology

AUTHOR

Stay in the loop with the Kosli newsletter

Get the latest updates, tutorials, news and more, delivered right to your inbox
Kosli is committed to protecting and respecting your privacy. By submitting this newsletter request, I consent to Kosli sending me marketing communications via email. I may opt out at any time. For information about our privacy practices, please visit Kosli's privacy policy.
Kosli team reading the newsletter

Got a question about Kosli?

We’re here to help, our customers range from larges fintechs, medtechs and regulated business all looking to streamline their DevOps audit trails

Contact us
Developers using Kosli