git rm *不会一次删除所有文件

问题描述 投票:7回答:4

我正在尝试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

git
4个回答
23
投票

通配符由shell扩展,默认情况下,扩展在大多数shell中不包括点文件。

所以当git执行时,第一个命令就变成了

git rm -r folder testfile3

第二个可能是文字

git rm -r *

然后git自己扩展。

由于remarked by Keith,一次性删除所有内容,阻止shell扩展通配符,以便git第一次进行扩展。这可以使用双引号或单引号,或者在星号前使用反斜杠来完成。我倾向于选择单引号:

git rm -r '*'

5
投票

壳牌全球化

当你运行git rm *时,你实际上是使用shell的globbing规则将参数传递给git-rm(1)。默认情况下,许多shell不包含隐藏文件(例如带有前导点的文件)。在Bash中,您可以使用dotglobGLOBIGNORE更改globbing规则。例如:

  • 使用内置的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 *

4
投票

正如用户1283885在评论中指出的那样,shell第一次扩展了*

第二次删除点文件的原因是,一旦没有要匹配的文件,shell就会将文字星号作为参数(取决于你的shell,至少有一个变量错误),然后git自己做匹配。


0
投票

请注意,正确的语法应该是git rm -r .('dot')

更令人担忧的是git rm -r(空路径规则字符串),它直到Git 2.11才一样!

请参阅commit d426430Emily Xie (emilyxxie)(2016年6月22日)。 (由Junio C Hamano -- gitster --commit 3b1e135合并,2016年10月26日)

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日)。 (2017年11月6日在Junio C Hamano -- gitster --commit 728c573合并)

作为pathspec元素的空字符串匹配所有路径。 但是,一个错误的脚本可能会意外地将一个空字符串分配给一个变量,然后传递给Git命令调用,例如:

path=... compute a path to be removed in $path ...
git rm -r "$path"

这会无意中删除当前目录中的所有路径。

© www.soinside.com 2019 - 2024. All rights reserved.