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

时间:2014-04-18 06:34:14

标签: git

根据帮助,没有-x选项git clean应该更不用说被忽略的文件,但事实并非如此。

[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已删除。这是一个错误吗?

5 个答案:

答案 0 :(得分:5)

根据man git clean

-d
    Remove untracked directories in addition to untracked files.

在您的情况下,不跟踪目录conf/sar - 它不包含由git跟踪的任何文件。如果你没有gitignore规则并执行了git clean -fd,那么这个未跟踪目录的内容就会被删除 - 只是文档说的。

现在,如果您添加带有规则的.gitignore来忽略*.sar个文件,则不会更改您的目录conf/sar/仍然未跟踪并且未跟踪文件aaa.sar的基本事实有资格使用此gitignore规则不应突然使git clean -fd无法删除。

但是,如果您在忽略的aaa.sar旁边添加任何跟踪文件,则不会删除此目录,并且您的文件将保持不变。

换句话说,虽然它看起来令人困惑,但这不是一个错误,git正是文档所说的。

答案 1 :(得分:4)

警告:此git clean行为会随Git 2.14(2017年第3季度)而略有变化

&#34; .virtualenvs/sms/local/lib/python2.7/site-packages/requests/‌​adapters.py", line 502, in send raise ProxyError(e, request=request) requests.exceptions.ProxyError: HTTPSConnectionPool(host='api.twilio.com', port=443): Max retries exceeded with url: /2010-04-01/Accounts/XXXXXXXXX/Messages.json (Caused by ProxyError('Cannot connect to proxy.', NewConnectionError('<urllib3.connection.Verif iedHTTPSConnection object at 0x7fa41a55e090>: Failed to establish a new connection: [Errno 111] Connection refused',))) 用于清除已忽略文件的目录,即使该命令不应丢失,但没有&#34; git clean -d"&#34;。
&#34; -x&#34;如果没有&#34; git status --ignored&#34;。

,则不会列出忽略和未跟踪的文件

commit 6b1db43(2017年5月23日),commit bbf504acommit fb89888commit df5bcdfcommit 0a81d4acommit b3487cc(2017年5月18日) Samuel Lijin (sxlijin) (由Junio C Hamano -- gitster --合并于commit f4fd99b,2017年6月2日)

  

-uall:教clean保留被忽略的路径

     

隐含的假设是,仅包含未跟踪和忽略路径的目录本身应被视为未跟踪。这在我们询问是否应该将目录添加到git数据库的用例中是有意义的,而不是在我们询问是否可以从工作树中安全地删除目录时;因此,clean -d会假设&#34;未跟踪&#34;可以删除包含被忽略路径的目录,即使这样做也会删除被忽略的路径。

     

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

答案 2 :(得分:0)

是的,git clean似乎与文档相反,即使未指定-x / -X,也会删除被忽略的文件。

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

我不知道这是疏忽还是故意的,但是这方面的联合页面显然是不完整的。您可以考虑将该联机帮助页的修补程序发送到git邮件列表。

顺便说一下,问题How to preserve all ignored files in git clean -fd?中讨论了同样的问题。在那里注意到git clean -df不会删除.gitignore中的目录。因此,要保留conf/,您可以将其添加到.gitignore

答案 3 :(得分:0)

要获得所需的行为,保护未跟踪的目录免受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

(或git ls-files --exclude-standard '-x!/conf/'只跳过一个规范)。单引号是因为!是用于拉入以前命令行的交互式shell语法。

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

接近所需行为
find -depth -type d -empty -delete
# -delete is -exec rm -f '{}' ';' on non-GNU userlands

但是这真的属于一个makefile配方,后面跟着一批mkdir -p来重新创建你想要保留的任何结构,即使是空的,因为make是为了管理像构建/这样的瞬态而构建的测试/安装产品。

答案 4 :(得分:0)

除了git clean修复I mentioned previously之外,在Git 2.28(2020年第三季度)中,对“ git clean”的代码清除还修复了最近的性能下降问题。

请参见commit 7233f17commit f7f5c6ccommit 351ea1ccommit e6c0be9Elijah Newren (newren)(2020年6月11日)。
(由Junio C Hamano -- gitster --commit 5367469中合并,2020年6月25日)

clean:优化并记录我们递归到子目录的情况

报道者:Brian Malehorn
签名人:伊利亚·纽伦

提交6b1db43109(“ clean:教导clean -d以保留忽略的路径”,2017-05-23,Git v2.14.0-rc0-merge在{{ 3}})在git-clean中添加了以下代码块以及其他代码:

if (remove_directories)
    dir.flags |= DIR_SHOW_IGNORED_TOO | DIR_KEEP_UNTRACKED_CONTENTS;

在提交消息中已很好地记录了这些标志的原因,但仅通过查看代码并不清楚。

在代码中添加一些说明以使其更清晰。

此外,看来git-2.26无法正确处理来自batch #5的标志组合。

在同时设置了这些标志和未设置DIR_SHOW_IGNORED_TOO_MODE_MATCHING的情况下,git应该递归到所有未跟踪和忽略的目录中。

git-2.26.0显然没有这样做。

我不知道其全部原因,也不知道git <2.27.0是否由于该不当行为而存在其他未知的错误,因为我不认为这值得研究。

根据git clean(“ dir中记录的巨大变化和疯狂:用线性算法代替指数算法”,2020-04-01,Git v2.27.0-rc0-{{ 3}}在commit 8d92fb2927中列出),旧算法一团糟,被扔掉了。

我能说的是git-2.27.0可以通过这种组合正确地循环到未跟踪和忽略的目录中。

但是,在干净的情况下,我们不需要递归到被忽略的目录中。那只是浪费时间。

因此,当git-2.27.0开始正确处理这些标志时,我们得到了性能回归报告。

使用merge中专门添加的fill_directory()值,而不是依靠DIR_SHOW_IGNORED_TOO_MODE_MATCHING以前的逻辑中的其他错误来提供跳过被忽略目录的行为。 1}}:添加选项以不同方式显示被忽略的文件”,2017-10-30,Git v2.16.0-rc0-batch #5中列出的commit eec0f7f2b7)。