2022:
这应该不再是Git 2.35 (Q1 2022) 的问题
不再有“fatal: Unable to read current working directory: No such file or directory”
2019:原始答案:
在此June 2018 thread 中紧随其后,报告为“git rm bug”
TLDR;这不是错误。
当从提交 X 移动到 Y 时,任何 Git 命令都不应该让树处于这样一种状态,如果您重新克隆,您将不会得到相同的 Y。
进入话题:
概览
"git rm" 将删除比指定更多的文件。这是一个错误或未记录的行为(不在手册页中)。
设置
-
在 git 存储库中,创建一个空目录或一个空目录链
$ mkdir -p path/to/some/
-
在最深的目录中创建一个文件并添加到跟踪中
$ touch path/to/some/file
$ git 添加路径/到/一些/文件
$ git commit -m '添加路径/到/一些/文件'
错误
对跟踪的文件运行“git rm”。
预期行为
$ git rm path/to/some/file
rm 'path/to/some/file'
$ ls path
to/
$ ls path/to
some/
请注意,path/、path/to/ 和 path/to/some/ 仍然存在。
实际行为
$ git rm path/to/some/file
rm 'path/to/some/file'
$ ls path
ls: cannot access 'path': No such file or directory
尽管 git 仅输出“rm 'path/to/some/file'”,但删除了整个空目录链。
只有在删除跟踪文件后链中的所有目录都为空时才会发生这种情况。
此行为未记录在手册页中。
我建议将“rmdir”语句添加到“git rm”输出中,或者更新手册页以反映这种行为。
一般原则是:
Git 无法跟踪空目录。
由于这是整个层次结构中的唯一内容,因此必须删除整个层次结构。
从d9b814cc97 ("Add builtin "git rm" command", 2006-05-19, Git v1.4.0-rc1) 开始,这种行为似乎已经存在很多年了。
有趣的是,Linus 在提交消息中指出,前导目录的删除与 git-rm 是一个 shell 脚本时不同。
他想知道是否值得选择控制
这种行为。
我想大多数用户要么想要当前的行为
或者他们很少遇到这种情况并感到惊讶,因为
long git rm 就是这样工作的。
这也与 Git 中删除文件的其他部分一致。例如。,
"git checkout" 到没有文件的状态将删除
前导目录(当然,如果它们是空的)。
更笼统地说:
我将逆向和固执,并建议当前的行为很好,因为没有任何其他行为的令人信服的理由。
对于挂在空目录上的所有防御措施总是沸腾
归结为,“我将来可能会做一些期望这些目录存在的事情。”
好吧,如果是这样的话,那么当你需要它们时创建它们——你所做的任何事情都不应该简单地假设基本目录的存在。
此外,通过“取消跟踪”这些目录,您建议
Git 悄悄地做通常应该由“git rm --cached”做的事情。
如果我想要这种行为,我宁愿自己输入。
举例说明为什么不删除空文件夹会有问题:
其他人已经说了原因,但这里有一个你可能没有的极端情况
想到了:
(
rm -rf /tmp/repo &&
git init /tmp/repo &&
cd /tmp/repo &&
mkdir -p foo/bar/baz &&
git status
)
如果您只有空目录“git status”将不会报告任何内容,
虽然“git clean -dxfn”会显示要清理的内容。
因此,如果这按您的建议进行,那么有人可以git rm some
文件,然后一切都会报告他们正在提交XYZ,但如果他们在该提交处重新克隆,他们会得到一棵看起来不同的树。
任何 Git 命令都不应该以将树留在
从提交 X->Y 移动时的状态,如果你不会得到相同的 Y
你重新克隆了。
注意:Git 存储库本身的官方git rm test (git/git/t/t3600-rm.sh) 非常清楚它的预期:
test_expect_success 'rm removes subdirectories recursively' '
mkdir -p dir/subdir/subsubdir &&
echo content >dir/subdir/subsubdir/file &&
git add dir/subdir/subsubdir/file &&
git rm -f dir/subdir/subsubdir/file &&
! test -d dir