In the life of every big git repository there is a moment when a massive, yet simple change is required, for example:

  • adoption of a new code style, or enforcing a style over the entire repo;
  • changing of a widely used common practice (like switching from include guards to pragma once in C++ code);
  • a widely used file/function/dependency needs to be renamed;

These changes will “separate” the git history to before and after such massive commit, making the use of git blame quite challenging.

Ignore specific commits during blame

As usual, git has an option to workaround this. We can instruct git to ignore specific commits during blame operation:

git blame --ignore-rev 1dc479a9 -- filename

We can save full hashes of such commits into a file (let’s call it .git-blame-ignore-revs):

1dc479a9f9876b4c095a1665e1f206ddc76acdc8  # adoption of a new code style
ANOTHER_COMMIT_HASH  # massive renaming

and pass this file to git:

git blame --ignore-revs-file .git-blame-ignore-revs -- filename

To avoid typing this parameter every time, it’s possible to add it to the repo-local config. Then git will pick this file for every git blame operation:

git config --local blame.ignoreRevsFile .git-blame-ignore-revs
git blame -- filename  # will automatically use .git-blame-ignore-revs file

Note: if this option is added to the global git configuration - git config --global blame.ignoreRevsFile .git-blame-ignore-revs - git will try to use this file for every repository in the system, and if a repository does not have this file, git will error out:

git blame -- filename
fatal: could not open object name list: .git-blame-ignore-revs

Integrations

GitHub and GitLab support .git-blame-ignore-revs file. It must be in the root of the repository and must have exactly this name.

It seems that BitBucket doesn’t support this.