当我对文件夹中的文件运行 git blame 时,例如:
git blame Foo/FileA.txt
返回
致命:HEAD 中没有这样的路径“Foo/FileA.txt”
我可以清楚的看到这个文件存在于文件系统中,同一个文件夹下的其他文件可以被成功追责——那么这是怎么回事呢?
我发布了这个问题和答案,因为它让我今天困惑了一段时间,我找不到一个能满足所有解决方案的答案。
最佳答案
这是由于使用仅因大小写而异的新名称重命名了文件系统上的父文件夹 - 并且在文件夹重命名之前发生的提交中添加了一些文件。这是来自 Powershell 提示的重现:
mkdir C:\RenameProblem
cd C:\RenameProblem
git init
mkdir foo
"FileA" > foo/FileA.txt
git add foo/FileA.txt
git commit -m "Add FileA"
然后在 Windows 资源管理器中,将目录“foo”重命名为“Foo”,然后在 Powershell 中继续:
"FileB" > Foo/FileB.txt
git add Foo/FileB.txt
git commit -m "Add FileB"
在这一点上,git blame/Foo/FileA.txt
(由于文件夹已重命名,将生成哪个选项卡完成)将失败并出现没有这样的路径错误,而 git blame/Foo/FileB.txt
甚至 git blame/foo/FileA.txt
都会成功。
此外,调用 git ls-files Foo
将只列出 FileB.txt
而 git ls-files foo
将只列出 FileA.txt
。在 Windows 上不是一个好地方。
在我的例子中,我有大量文件在两个版本的文件夹名称之间拆分。
您可以通过使用 git mv
重命名文件来解决此问题:
git mv foo/FileA.txt Foo/FileA.txt
git commit -am "Rename foo to Foo"
如果您需要重命名很多文件,请使用一些 Powershell(另外,请注意 git mv
有一个 -n
开关来执行“what-如果“试运行,这样你就可以检查你的重命名是否正确):
git ls-files foo | % { (& git mv $_ $('F' + $_.Substring(1))) }
上面使用 git ls-files
获取问题“foo”文件夹中的文件列表,将其通过管道传输到“ForEach”(%
是快捷方式为此)然后为每个提供原始名称($_
)和“F”的新名称以及文件名的其余部分('F' + $_.Substring(1))
)
关于git blame on windows 报告 "fatal: no such path <path> in HEAD",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42077734/