When I run git blame on a file in a folder e,g,:
git blame Foo/FileA.txt
it returns
fatal: no such path 'Foo/FileA.txt' in HEAD
I can clearly see that this file exists on the file system, and other files in the same folder can be successfully blamed - so what is going on?
I'm posting this question and answer as it had me stumped for a while today, and I couldn't find a single answer that hit all of the solution.
Another possibility is that the file or a containing directory are a symbolic link. You can use
ls -l
to verify this is the case. Try to blame the file in its original location instead.This is due to renaming a parent folder on the file system with a new name that varies only by case - and some files were added in a commit occurring before the rename of the folder. Here is a repro, from a Powershell prompt:
Then in windows explorer, rename directory "foo" to "Foo" and then continue in Powershell with:
At this point,
git blame /Foo/FileA.txt
(which tab completion will generate since the folder has renamed) will fail with the no such path error, whereasgit blame /Foo/FileB.txt
or evengit blame /foo/FileA.txt
will succeed.Futhermore, a call to
git ls-files Foo
will list onlyFileB.txt
andgit ls-files foo
will list onlyFileA.txt
. Not a great place to be on Windows.In my case, I had a large number of files split between the two versions of the folder name.
You can solve this by renaming the file with
git mv
:If you need to rename a lot of files, use a bit of Powershell (also, note that
git mv
has a-n
switch to do a "what-if" dry run, so you can check your rename is correct):The above uses
git ls-files
to get a list of files in the problem "foo" folder, pipes this into a "ForEach" (%
is the shortcut for that) and then executesgit mv
for each file supplying the original name ($_
) and the new name of 'F' and the rest of the file name ('F' + $_.Substring(1))
)