Developing software in the Real World

Ignoring mass reformatting commits with git blame

I’ve recently merged a PR by Stephen to rst2df that reformats the entire codebase to align with PEP 8. As rst2pdf is over a decade old, this has resulted in a lot of changes to the files which now have Stephen’s name attached. This affects git blame.

For example:

Stephen is now implicated as having changed this for loop, but all he did was run the tool that reformatted it.

--ignore-rev to the rescue!

Fortunately, this can be resolved by using --ignore-rev. From the docs:

Ignore changes made by the revision when assigning blame, as if the change never happened. Lines that were changed or added by an ignored commit will be blamed on the previous commit that changed that line or nearby lines. This option may be specified multiple times to ignore more than one revision.

Re-running our command ignoring the re-formmatting commit:

Now, we can see that the actual change by Roberto was in March 2019, and I particularly like that the formatting update remains so the line numbers continue to match up with my editor.

Magic!

Store the ignored commits in a file

Remembering to type --ignore-rev 825ba00b will get tedious quite quickly and who remembers commit hashes anyway? To help with this, git blame also supports writing the commit hashes into a file and then referencing the file with --ignore-revs-file.

We create .git-blame-ignore-revs like this:

Each commit has to be the full 40 character hash and we’re allowed comments.

We can then ignore all the commits in the file with:

But there’s more!

We can tell git the name of the file and then git blame will always use it:

Note that this needs to set per-project as git blame will error if it cannot find the file.

Now, our original command does exactly what we want:

Now we never need to think about the mass reformatting ever again!

Truly magic!

6 thoughts on “Ignoring mass reformatting commits with git blame

  1. Is there a way you can make git blame automatically use the ignore revs file without everyone needing to set the config option locally? Like saving that in the remote repository?

    1. Thanks for the post Rob, very useful!

      In case this helps someone else: in my team we use GitLens on VSCode, so I wanted to see how to add the ignore-revs file to it.
      Reading their source, they have a good example on how to do this: just add "gitlens.advanced.blame.customArguments": ["–ignore-revs-file", "name-of-your-file"] to your to .vscode/settings.json

        1. You’re right. Local git scope will have to be .git/config which cannot be checked in.
          A solution employed by commit-lint is to write to that directory as part of a project’s post-install hook, which might be an option to configure ignore-revs

Thoughts? Leave a reply

Your email address will not be published. Required fields are marked *