我正在尝试git的一些示例说明并遇到了这种特殊情况:当我们执行git rm *
时,它不会在第一次尝试时删除.*
文件。
为什么会这样?
mkdir -p test_repo1/folder && cd test_repo1
touch .testfile1 .testfile2 testfile3 folder/testfile4 folder/.testfile5
git init && git add . && git commit -m "test commit"
如果现在我按照以下方式执行git rm
,我必须再次删除所有文件
$ git rm -r *
rm 'folder/.testfile5'
rm 'folder/testfile4'
rm 'testfile3'
$ git rm -r *
rm '.testfile1'
rm '.testfile2'
为什么git在第一次尝试时不删除所有文件?另外,为什么仅对具有repo root的文件发生这种情况?
有趣的是,如果我只有那些.testfiles
,那么git会在第一次尝试中删除它们。
我正在使用git版本1.7.9.5
答案 0 :(得分:23)
通配符由shell扩展,默认情况下,扩展在大多数shell中都不包括点文件。
因此,当git
执行时,第一个命令变为
git rm -r folder testfile3
,第二个可能是文字
git rm -r *
git
然后自行扩展。
作为remarked by Keith,一次性删除所有内容,阻止shell扩展通配符,以便git
第一次进行扩展。这可以使用双引号或单引号,或者在星号前使用反斜杠来完成。我倾向于选择单引号:
git rm -r '*'
答案 1 :(得分:5)
运行git rm *
时,实际上是使用shell的通配规则将参数传递给git-rm(1)。默认情况下,许多shell不包含隐藏文件(例如带有前导点的文件)。在Bash中,您可以使用dotglob和GLOBIGNORE更改通配规则。例如:
使用 shopt 内置:
# set dotglob
shopt -s dotglob
git rm *
# unset dotglob
shopt -u dotglob
使用 GLOBIGNORE 变量(也设置 dotglob ):
# Run git within a modified environment that includes GLOBIGNORE.
GLOBIGNORE='.git' git rm *
答案 2 :(得分:4)
正如评论中提到的user1281385一样,shell第一次扩展*
。
第二次时间删除点文件的原因是,一旦没有要匹配的文件,shell就会将文字星号作为参数(取决于你的shell,至少有一个变体)反而出错了)然后git自己做匹配。
答案 3 :(得分:0)
请注意,正确的语法应为git rm -r .
(' dot')
更令人担忧的是git rm -r
(空路径规范字符串),直到Git 2.11才会这样做!
commit d426430见Emily Xie (emilyxxie
)(2016年6月22日)
(Junio C Hamano -- gitster
--于2016年10月26日commit 3b1e135合并)
pathspec
:警告空字符串为pathspec作为pathspec元素的空字符串匹配所有路径 但是,一个错误的脚本可能会意外地将一个空字符串分配给一个变量,然后传递给Git命令调用,例如:
path=... compute a path to be removed in $path ...
git rm -r "$paht"
会无意中删除当前目录中的所有路径。
此问题的修复需要两步法。
由于可能存在故意以这种方式使用空字符串的现有脚本,因此第一步只是发出警告:(1)告诉空字符串将成为无效的pathspec元素,并且(2)询问用户 使用"
.
"如果他们的意思是匹配所有。对于第二步,后续补丁将在几个发布周期后进行 删除警告并改为抛出错误。
Git 2.15.x / 2.16更新(2018年第一季度):
消息"将在即将发布的版本中变为无效"消失,变成:
empty string is not a valid pathspec.
please use . instead if you meant to match all paths
commit 9e4e8a6见Emily Xie (emilyxxie
)(2017年6月7日)
请commit 229a95a查看Junio C Hamano (gitster
)(2017年6月23日)
(Junio C Hamano -- gitster
--合并于commit 728c573,2017年11月6日)
作为pathspec元素的空字符串匹配所有路径 但是,一个错误的脚本可能会意外地将一个空字符串分配给一个变量,然后传递给Git命令调用,例如:
path=... compute a path to be removed in $path ...
git rm -r "$path"
会无意中删除当前的所有路径 。目录