Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't git blame --ignore-rev/--ignore-revs-file work for me?

git blame --ignore-revs-file is clearly an option that exists in modern Git.

There's only one problem. It doesn't work.

Or at least, it doesn't work for me:

You can add this in a shell script:

mkdir -p /tmp/blarp
cd /tmp/blarp
git init
cat << EOF > file.txt
one
two
three
EOF
git add file.txt
git commit --author "One <[email protected]>" -m 'one commit'
cat << EOF > file.txt
one
awesome
three
EOF
git add file.txt
git commit --author "Two <[email protected]>" -m 'two commits'
cat << EOF > file.txt
one
awesome
sauce
EOF
git add file.txt
git commit --author "One <[email protected]>" -m 'three commits'
git rev-parse HEAD~1 > ignore.txt
git blame --ignore-revs-file=ignore.txt file.txt

For me this shows:

^b6d40d5 (One 2019-12-30 21:47:15 +0000 1) one
1c185c4c (Two 2019-12-30 21:47:15 +0000 2) awesome
d8b9bafd (One 2019-12-30 21:47:15 +0000 3) sauce

But I expect to see

^b6d40d5 (One 2019-12-30 21:47:15 +0000 1) one
^b6d40d5 (One 2019-12-30 21:47:15 +0000 2) two
d8b9bafd (One 2019-12-30 21:47:15 +0000 3) sauce

or

^b6d40d5 (One 2019-12-30 21:47:15 +0000 1) one
d8b9bafd (One 2019-12-30 21:47:15 +0000 2) awesome
d8b9bafd (One 2019-12-30 21:47:15 +0000 3) sauce

But this isn't the case. I did discover that if the changes were only whitespace changes they would be ignored... but the git documentation isn't explicit about this, just suggesting that:

--ignore-revs-file

Ignore revisions listed in file, which must be in the same format as an fsck.skipList. This option may be repeated, and these files will be processed after any files specified with the blame.ignoreRevsFile config option. An empty file name, "", will clear the list of revs from previously processed files.

Any clue why git blame --ignore-revs-file=revs-to-ignore doesn't seem to work correctly for me?

like image 819
Wayne Werner Avatar asked Dec 30 '19 21:12

Wayne Werner


People also ask

How do I use git blame ignore revs?

git-blame-ignore-revs . It expects one commit hash per line, and all commits in the file will be ignored by git blame . You can add comments to this file by prefixing it with a # , and I'd recommend commenting each sha to explain why it's being skipped. Once the file exists, you can run git blame --ignore-revs-file .

What is git blame used for?

Summary. The git blame command is used to examine the contents of a file line by line and see when each line was last modified and who the author of the modifications was. The output format of git blame can be altered with various command line options.


2 Answers

Check if Git 2.29 (Q4 2020) has fixed the isue: "git blame --ignore-rev/--ignore-revs-file"(man) failed to validate their input are valid revision, and failed to take into account that the user may want to give an annotated tag instead of a commit, which has been corrected.

See commit 610e2b9, commit f58931c (24 Sep 2020) by Junio C Hamano (gitster).
(Merged by Junio C Hamano -- gitster -- in commit 230ff3e, 04 Oct 2020)

blame: validate and peel the object names on the ignore list

The command reads list of object names to place on the ignore list either from the command line or from a file, but they are not checked with their object type (those read from the file are not even checked for object existence).

Extend the oidset_parse_file() API and allow it to take a callback that can be used to die (e.g. when an inappropriate input is read) or modify the object name read (e.g. when a tag pointing at a commit is read, and the caller wants a commit object name), and use it in the code that handles ignore list.


With Git 2.30 (Q1 2021), "git blame --ignore-revs-file=<file>(man)" learned to ignore a non-existent object name in the input, instead of complaining.

See commit c714d05 (10 Nov 2020) by René Scharfe (rscharfe).
(Merged by Junio C Hamano -- gitster -- in commit b4e245a, 18 Nov 2020)

blame: silently ignore invalid ignore file objects

Reported-by: Jean-Yves Avenard
Signed-off-by: René Scharfe
Reviewed-by: Barret Rhoden

Since 610e2b9240 ("blame: validate and peel the object names on the ignore list", 2020-09-24, Git v2.29.0-rc0 -- merge listed in batch #19) git blame(man) reports checks if objects specified with --ignore-rev and in files loaded with --ignore-revs-file and config option blame.ignoreRevsFile are actual objects and dies if they aren't. The intent is to report typos to the user.

This also breaks the ability to use a single ignore file for multiple repositories.
Typos are presumably less likely in files than on the command line, so alerting is less useful here.
Restore that feature by skipping non-commits without dying.

like image 66
VonC Avatar answered Sep 28 '22 08:09

VonC


TL;DR: the ignore-revs feature is designed for refactoring commits, not commits where lines are changed entirely.

Hi Wayne,

Thanks for trying it out. Sorry your first experience with it wasn't good. I think the docs could be improved to communicate the intent of the feature better.

git blame --ignore-rev is trying to find a line that is somewhat similar to "awesome". But "awesome" and "two" have nothing in common so it gives up and attributes "awesome" to the actual commit that added it.

There is a feature to identify this scenario, but it needs to be explicitly enabled:

If the blame.markUnblamableLines config option is set, then those lines touched by an ignored commit that we could not attribute to another revision are marked with a *.

Using this option, with your example script I see a * to indicate the problem:

^6bce3bb (One 2021-03-28 15:08:08 +0100 1) one
*b75aaf2 (Two 2021-03-28 15:08:08 +0100 2) awesome
5d3b18c7 (One 2021-03-28 15:08:08 +0100 3) sauce

If you try git blame --ignore-rev on a commit that you genuinely want to ignore (for example reformatting your code) then it should work well.

For example, if I change your script to replace two with awesome TWO then I see this:

^5307c74 (One 2021-03-28 15:14:52 +0100 1) one
^5307c74 (One 2021-03-28 15:14:52 +0100 2) awesome TWO
9d3fcc01 (One 2021-03-28 15:14:52 +0100 3) sauce
like image 39
Michael Platings Avatar answered Sep 28 '22 10:09

Michael Platings