我移动了一些文件后,添加/暂存他们。文件结构看起来像:
parent/dir1/script0.py
parent/dir1/script1.py
parent/script0_delete_me.py
parent/script1_delete_me.py
在dir1
内部运行git rm -f ../*.py
时(注意,我没有指定-r
),我期望的结果是:
parent/dir1/script0.py
parent/dir1/script1.py
parent/
parent/
但事实是
parent/dir1/
parent/dir1/
parent/
parent/
取回我需要的文件没有问题。但是为什么git rm -f ../*.py
要递归搜索,即使-r
从来没有被给定过?快速浏览git rm -f
的文档表明递归搜索需要-r
选项。
常规bash的行为不是这样的:
~/test/dir1$ ls ../
dir1 d.py
~/test/dir1$ rm -f ../*.py
~/test/dir1$ ls
d.py
编辑:复制:
~$ git init t
Initialized empty Git repository in ~/t/.git/
~$ cd t
~/t$ touch d.py
~/t$ git add d.py
~/t$ git commit -m "init"
[master (root-commit) f59e049] init
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 d.py
~/t$ mkdir u
~/t$ git mv d.py u/d.py
~/t$ cd u
~/t/u$ ls
d.py
~/t/u$ ls ../
u
~/t/u$ git rm -f ../*.py
rm 'u/d.py'
~/t/u$ ls
~/t/u$
我想可能是我没有正确地看待这个问题/试图用错误的方式做一些事情。但这种行为仍然看起来很奇怪。
1条答案
按热度按时间ercv8c1e1#
Git的命令行路径规范有它的怪癖,shell globbing也有它的怪癖。
简短的形式是,您希望使用
git rm -f ':(glob)../*.py'
,或者在脚本或shell启动(可能是~/.bashrc
)中设置nullglob
或failglob
来运行,以避免这种情况,嗯,可能过于急切,在不必显式警告shell关闭的情况下输入模糊的命令参数。Git命令行路径规范不会特别处理目录分隔符,而shell glob则会,许多shell会将不匹配的glob沿着给命令,以防它实际上不是文件名,命令会以其他方式理解字符串。
因此,由于父目录中没有以
.py
结尾的路径,Git将rm
、-f
和*.py
视为args,而Git的rm
将其解释为Git路径规范。无论是在shell还是在Git中,改变这些行为的痛苦/收益比都是无法忍受的。说
git help glossary
,然后搜索pathspec
,看看你可以用它做的很多有时候非常方便的事情。怀疑地盯着这个,然后试试看:
这里还有几个怪癖在起作用,这就是它的工作方式,每一个选择都迎合了工作流的特定部分,有些人经常点击,而有些人几乎从来没有。