How do I "git blame" a deleted line?
git blame
is great for modified and added lines, but how can I find when a line that existed in a specific previous commit was eventually deleted. I'm thinking bisect
, but I was hoping for something handier.
(Before you ask: in this case, I just did a git log -p
and searched through for the code line and (a) some idiot had just deleted the vital line in the previous commit and (b) I was that idiot.)
Solution 1:
If you know the contents of the line, this is an ideal use case for:
git log -S <string> path/to/file
which shows you commits which introduce or remove an instance of that string. There's also the -G<regex>
which does the same thing with regular expressions! See man git-log
and search for the -G
and -S
options, or pickaxe (the friendly name for these features) for more information.
The -S
option is actually mentioned in the header of the git-blame
manpage too, in the description section, where it gives an example using git log -S...
.
Solution 2:
I think what you really want is
git blame --reverse START..END filename
From the manpage:
Walk history forward instead of backward. Instead of showing the revision in which a line appeared, this shows the last revision in which a line has existed. This requires a range of revisions like START..END where the path to blame exists in START.
With git blame reverse
, you can find the last commit the line appeared in. You still need to get the commit that comes after.
You can use the following command to show a reversed git log. The first commit shown will be the last time that line appears, and the next commit will be when it is changed or removed.
git log --reverse --ancestry-path COMMIT^..master
Solution 3:
Just to complete Cascabel's answer:
git log --full-history -S <string> path/to/file
I had the same problem as mentioned here, but it turned out that the line was missing, because a merge commit from a branch got reverted and then merged back into it, effectively removing the line in question. The --full-history
flag prevents skipping those commits.