You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

未加-r参数时git rm -f ../*.py为何递归删除文件?

为什么git rm -f ../*.py会删除子目录中的文件?

核心原因:通配符的处理主体不同

  • 常规bash的rm命令:*.py这类通配符由shell负责展开。当你在dir1目录执行rm -f ../*.py时,shell会先扫描../目录,把../*.py展开成该目录下所有后缀为.py的具体文件名(比如../script0_delete_me.py),随后rm仅处理这些明确的文件,不会触及子目录内容。
  • git rm命令:通配符由Git自身解析,而非shell。Git会将../*.py理解为「仓库中所有文件名匹配*.py的跟踪文件」——匹配规则基于文件在仓库中的完整路径的文件名部分,而非当前目录的相对路径范围。

结合你的复现场景拆解

在你的测试流程中:

  1. 将d.py移动到u/d.py后,Git跟踪的文件路径为u/d.py
  2. 当你在u目录执行git rm -f ../*.py时,Git未让shell展开通配符,而是自行解析规则:
    • Git从仓库根目录出发,遍历所有跟踪文件,只要文件名符合*.py就会被选中。u/d.py的文件名是d.py,完全匹配规则,因此被删除。
    • 命令中的../仅代表当前目录的上级路径,但Git的通配符匹配不受该相对路径限制,它会扫描整个仓库的文件名。

如何避免这种情况?

如果只想删除上级目录下的.py文件,需要让shell先展开通配符,再传递给git rm,比如:

git rm -f ../*.py
# 或者直接指定具体文件名,彻底避免通配符歧义
git rm -f ../script0_delete_me.py ../script1_delete_me.py

(注:若上级目录无匹配的.py文件,shell会把../*.py原样传给Git,仍会触发Git的通配符解析,因此直接指定文件名是更稳妥的方式)

对比验证

你提到常规rm不会出现这个问题,正是因为shell先完成了通配符展开,rm拿到的是明确的上级目录文件路径,自然不会触及子目录里的内容。

内容的提问来源于stack exchange,提问作者Ralph

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 06:21:37