根据帮助,没有-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
已删除。这是一个错误吗?
答案 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季度)而略有变化
" .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 bbf504a,commit fb89888,commit df5bcdf,commit 0a81d4a,commit 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 7233f17的commit f7f5c6c,commit 351ea1c,commit e6c0be9,Elijah 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)。