git应该删除空目录吗?

pax*_*blo 5 git

我最近对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在不关心目录时会删除目录。

Von*_*onC 8

2018年6月的该线程中遵循此规则,该线程报告为“ git rm bug

TLDR;这不是错误。

没有Git的命令的行为应该以这样的方式为从提交移动时离开树的状态XY,你会不会得到同样的Y,如果你再克隆。

进入线程:

总览

git rm”将删除比指定数量更多的文件。这是错误或未记录的行为(不在手册页中)。

设定

  1. 在git仓库中,创建一个空目录或一个空目录链

    $ mkdir -p path / to / some /

  2. 在最深目录中创建文件并将其添加到跟踪

    $ touch path / to / some / file $ git add path / to / some / file $ git commit -m'添加路径/ to / some / file'

错误

git rm在跟踪的文件上运行' '。

预期的行为

$ git rm path/to/some/file
rm 'path/to/some/file'
$ ls path
to/
$ ls path/to
some/
Run Code Online (Sandbox Code Playgroud)

需要注意的是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
Run Code Online (Sandbox Code Playgroud)

尽管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”执行的操作。
如果我想要这种行为,我宁愿自己键入。

例如,为了说明为什么删除空文件夹会有问题:

其他人已经说过原因,但这是您可能没有想到的一个极端情况:

(
    rm -rf /tmp/repo &&
    git init /tmp/repo &&
    cd /tmp/repo &&
    mkdir -p foo/bar/baz &&
    git status
)
Run Code Online (Sandbox Code Playgroud)

如果您只有空目录,则“ 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)