Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
`git clean`默认情况下删除被忽略的文件?_Git - Fatal编程技术网

`git clean`默认情况下删除被忽略的文件?

`git clean`默认情况下删除被忽略的文件?,git,Git,根据帮助,没有-x选项gitclean应该更不用说被忽略的文件了,但是它没有 [il@reallin test]$ cat .gitignore *.sar [il@reallin test]$ mkdir -p conf/sar && touch conf/sar/aaa.sar [il@reallin test]$ git status # On branch master nothing to commit, working directory clean [il@real

根据帮助,没有
-x
选项
gitclean
应该更不用说被忽略的文件了,但是它没有

[il@reallin test]$ cat .gitignore
*.sar
[il@reallin test]$ mkdir -p conf/sar && touch conf/sar/aaa.sar
[il@reallin test]$ git status
# On branch master
nothing to commit, working directory clean
[il@reallin test]$ git clean -df
Removing conf/

conf/sar/aaa.sar
被删除。这是一个bug吗?

根据
man git clean

-d
    Remove untracked directories in addition to untracked files.
if (remove_directories)
    dir.flags |= DIR_SHOW_IGNORED_TOO | DIR_KEEP_UNTRACKED_CONTENTS;
在您的情况下,目录
conf/sar
不被跟踪-它不包含任何由git跟踪的文件。如果您没有gitignore规则并执行了
git clean-fd
,则此未跟踪目录的内容将被删除—正如文档所述

现在,如果您添加了
.gitignore
,规则为ignore
*.sar
文件,它不会改变您的目录
conf/sar/
仍然未跟踪的基本事实,并且具有符合此gitignore规则的未跟踪文件aaa.sar不应该突然使其无法通过
git clean-fd
进行移动

但是,如果您在被忽略的
aaa.sar
旁边添加任何跟踪文件,则不会删除此目录,您的文件将被单独保留


换句话说,虽然看起来很混乱,但这并不是一个bug,git完全按照文档所说的去做。

是的,
git clean
删除一个被忽略的文件,即使没有指定
-x
/
-x
,它的行为似乎与文档相反

选项
-d
似乎覆盖了
-x
/
-x
的缺失。也就是说,
git clean-df
将删除未跟踪的目录,即使它们包含未跟踪但被忽略的文件

我不知道这是疏忽还是故意的,但主页在这方面显然是不完整的。您可能会考虑向MIT邮件列表发送MangPoad的补丁。


顺便说一句,问题中也讨论了同样的问题。需要注意的是,
git clean-df
不会删除
.gitignore
中的目录。因此,要保留您的
conf/
,您可以将其添加到
.gitignore
以获得您想要的行为,保护未跟踪目录不受
git clean-d
的影响,并有选择地从这些未跟踪目录中删除内容,在您的情况下,您必须显式忽略整个最上面的未跟踪目录

echo /conf/ >>.gitignore   # or .git/info/excludes if it's just you
现在,
git clean
不会递归到未跟踪的目录中,但幸运的是,这是一个简单的操作:

# recursive x-ray git clean with various options:

git ls-files --exclude-standard '-x!*/' -oz  | xargs -0 rm -f   #
git ls-files                            -oz  | xargs -0 rm -f   # -x
git ls-files --exclude-standard '-x!*/' -oiz | xargs -0 rm -f   # -X
(或
gitls文件--排除标准'-x!/conf/'
以跳过一个规范)。单引号出现是因为
是一种交互式shell语法,用于插入以前的命令行

要清理空目录,您可以使用

find -depth -type d -empty -delete
# -delete is -exec rm -f '{}' ';' on non-GNU userlands
但这实际上属于makefile配方,然后是一批
mkdir-p
s来重新创建您想要保留的任何结构,即使是空的,因为
make
是用来管理构建/测试/安装产品等瞬态的

警告:使用Git 2.14(2017年第3季度)时,此行为将略有改变

git clean-d”
用于清理已忽略文件的目录,即使该命令在没有“
-x
”的情况下不应丢失已忽略的文件。
git status--ignored
”未列出被忽略和未跟踪的文件,但没有“
-uall

参见(2017年5月23日)和,,(2017年5月18日)的作者。
(于2017年6月2日被合并)

clean
:设定
clean-d
以保留忽略的路径 有一种隐含的假设,即只包含未跟踪和忽略路径的目录本身应被视为未跟踪。这在我们询问是否应该将目录添加到git数据库的用例中是有意义的,但在我们询问是否可以从工作树中安全地删除目录时则没有意义;因此,
clean-d
将假定包含被忽略路径的“未跟踪”目录可以被删除,即使这样做也会删除被忽略的路径

为了解决这个问题,我们教
clean-d
收集被忽略的路径,如果未跟踪的目录包含被忽略的路径,则跳过它,而只是删除其中未跟踪的内容。
要实现这一点,必须收集未跟踪目录的所有未跟踪内容,以及所有忽略的路径,以确定必须跳过哪些未跟踪的目录(因为它们包含忽略的路径)和不应跳过哪些未跟踪的目录

但是。。。自2017年以来,这一变化意味着
如中的报告和分析:

深度为120个目录,需要6*10^23年才能完成

这一减速是由以下因素造成的,这是经济衰退的一部分 修补程序系列修复“
git clean-d
”甚至删除未跟踪的目录 如果它们包含被忽略的文件

所以。。。修复正在进行中,将于2020年晚些时候发布


Git 2.24(2019年第4季度)说明了这一点,Git clean的行为改变引入了回归

参见作者(2019年8月25日)
(于2019年9月30日合并)

t7300 clean
:演示删除被忽略文件破损的嵌套回购 “
git clean-fd
”如果属于未跟踪目录,则不能删除该目录 到不同的Git存储库或工作树

不幸的是,如果外部存储库中的“
.gitignore
”规则恰好与嵌套存储库或工作树中的文件匹配,则会出现错误,“
git clean-fd
”会删除嵌套存储库工作树的内容 除了被忽略的文件,可能会导致数据丢失

添加以证明此破损

此问题是(
clean
:teach)中介绍的回归
clean-d
保留被忽略的路径,2017-05-23,Git v2.13.2)


Git 2.24进一步澄清了Git clean-d:

见(2019年10月1日)和(1)
git clean -ffd */ut
"dir"
"dir/file"
"dir"
git clean -f untracked_dir/file
git clean -f untracked_dir/file1 tracked_dir/file2
git clean -f untracked_dir_1/file1 untracked_dir_2/file2
git clean -f '*.o'
git clean -f '*/*.o'
one/two/three/four/five/somefile.txt
for depth in $(seq 10 25)
do
  dirs=$(for i in $(seq 1 $depth) ; do printf 'dir/' ; done)
  rm -rf dir
  mkdir -p $dirs
10: 0.03
11: 0.05
12: 0.08
13: 0.19
14: 0.29
15: 0.50
16: 1.05
17: 2.11
18: 4.11
19: 8.60
20: 17.55
21: 33.87
22: 68.71
23: 140.05
24: 274.45
25: 551.15
17.55 * 2^220 / (60*60*24*365) = 9.4 * 10^59 YEARS
if (remove_directories)
    dir.flags |= DIR_SHOW_IGNORED_TOO | DIR_KEEP_UNTRACKED_CONTENTS;