我最近对git rm目录(a)中的最后一个文件进行了处理,由于某种原因,它决定也删除该目录。我用一个新文件测试了行为,如下所示:
mkdir newdir
touch newdir/newfile
git add newdir/newfile
git commit
git rm newdir/newfile
Run Code Online (Sandbox Code Playgroud)
当我执行最后一行时,newdir目录完全消失。那是预期的行为吗?我的理解是,Git跟踪文件,而不是目录。
由于在执行上面的步骤(创建没有跟踪文件的目录)后不会抱怨,为什么仅由于我从目录中删除了最后一个跟踪文件而删除目录?
对于它的价值,我正在运行2.7.4版。
(a)我有一个带gitDummy文件的占位符目录,因此已将其推送到存储库。然后,我要添加大量真实文件,因此我删除了虚拟文件,然后尝试复制到新文件中,以准备添加,提交和推送。
瞧,由于目录已消失,复制操作失败。我怀疑如果删除假人之前在文件中复制它会起作用,但是仍然让我感到奇怪的是,Git在不关心目录时会删除目录。
在2018年6月的该线程中遵循此规则,该线程报告为“ git rm bug”
没有Git的命令的行为应该以这样的方式为从提交移动时离开树的状态X来Y,你会不会得到同样的Y,如果你再克隆。
进入线程:
总览
“
git rm”将删除比指定数量更多的文件。这是错误或未记录的行为(不在手册页中)。设定
在git仓库中,创建一个空目录或一个空目录链
$ mkdir -p path / to / some /
在最深目录中创建文件并将其添加到跟踪
$ touch path / to / some / file $ git add path / to / some / file $ git commit -m'添加路径/ to / some / file'
错误
git rm在跟踪的文件上运行' '。预期的行为
Run Code Online (Sandbox Code Playgroud)$ git rm path/to/some/file rm 'path/to/some/file' $ ls path to/ $ ls path/to some/需要注意的是
path/,path/to/和path/to/some/仍然存在。实际行为
Run Code Online (Sandbox Code Playgroud)$ 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(“添加内置的“ git rm”命令”,2006-05-19,Git v1.4.0-rc1)以来,这种行为似乎已经存在了很多年。
有趣的是,Linus在提交消息中指出,删除前导目录与git-rmshell脚本时不同。
而且他想知道控制该行为的选择是否值得。我想大多数用户要么希望当前的行为,要么很少遇到这种情况而感到惊讶,因为
git rm这种方式已经工作了多长时间。它也与Git删除文件的其他部分一致。例如,“
git checkout”到没有文件的状态将删除前导目录(当然,如果它们为空)。
更普遍:
我要保持逆势而固执,并建议当前的行为还可以,因为没有其他任何令人信服的理由。
始终,挂在空目录上的所有辩解都可以归结为:“将来我可能会做一些希望这些目录存在的事情。”
好吧,如果是这样,请在需要它们时创建它们-您所做的任何事情都不应简单地假设存在基本目录。另外,通过“取消跟踪”这些目录,您建议Git安静地执行通常应由“
git rm --cached”执行的操作。
如果我想要这种行为,我宁愿自己键入。
例如,为了说明为什么不删除空文件夹会有问题:
其他人已经说过原因,但这是您可能没有想到的一个极端情况:
Run Code Online (Sandbox Code Playgroud)( 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提交一些文件,那么所有内容都将报告他们正在进行提交XYZ,但是如果他们在提交时重新进行了克隆,则会得到一棵看起来不同的树。任何Git命令的行为都不应使树从提交移到退出复制后
X->Y不会得到的状态Y。
注意:关于Git回购本身的官方git rm测试(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
Run Code Online (Sandbox Code Playgroud)