git应该删除空目录吗?

时间:2019-04-03 03:59:10

标签: git

我最近对目录中的最后一个文件做了git rm {sup>(a),并且由于某种原因,它决定删除该目录。我用一个新文件测试了行为,如下所示:

mkdir newdir
touch newdir/newfile
git add newdir/newfile
git commit
git rm newdir/newfile

当我执行最后一行时,newdir目录完全消失。那是预期的行为吗?我的理解是,Git跟踪文件,而不是目录。

由于在执行上面的第一步后没有抱怨,因此没有跟踪文件的目录的创建,为什么仅仅因为我从目录中删除了最后一个跟踪文件而删除目录?

>

关于它的价值,我正在运行版本2.7.4。


(a)我有一个带有gitDummy文件的占位符目录,因此将其推送到存储库中。然后,我要添加很多 real 文件,因此我删除了虚拟对象,然后尝试将其复制到新文件中,以准备添加,提交和推送。

瞧,由于目录已消失,复制操作失败。我怀疑如果我将文件复制到之前删除该虚拟对象的话,它会起作用,但是仍然让我感到奇怪的是,Git在不关心目录时会删除目录。

1 个答案:

答案 0 :(得分:8)

在此June 2018 thread之后,它被报告为“ git rm bug

TLDR;这不是错误。

从提交X移至Y时,任何Git命令的行为都不应使树保持在某种状态,如果您这样做,您将不会得到相同的Y重新克隆。

进入线程:

  

概述

     

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

     

设置

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

         

    $ mkdir -p path / to / some /

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

         

    $ touch path / to / some / file   $ git添加路径/到/一些/文件   $ git commit -m'添加路径/到/某些/文件'

  4.   
     

臭虫

     

在跟踪的文件上运行'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无法跟踪空目录。
  由于那是整个层次结构中的 only 内容,因此必须删除整个层次结构。

     

d9b814cc97(“添加内置的“ git rm”命令”,2006-05-19,Git v1.4.0-rc1)以来,这种行为似乎已经存在了很多年。
  有趣的是,Linus在提交消息中指出,删除前导目录与git-rm是shell脚本时有所不同。
  他想知道是否值得选择控制   这种行为。

     

我想大多数用户要么想要当前行为   或他们很少碰到这个,并惊讶于   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   文件,那么所有内容都会报告它们正在提交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