侧边栏壁纸
博主头像
一笑痕

人生若只如初见,
是可喜亦或者是可悲?

  • 累计撰写 253 篇文章
  • 累计收到 7 条评论

执行 git clean 前,先看 -n 列出哪些路径

2026-10-28 / 0 评论 / 2 阅读

执行 git clean 前,先看 -n 列出哪些路径

仓库里堆了几个临时文件,想清掉却不想误删素材。git clean 的预览选项是 -n:它只列出候选项,不会删除。用临时仓库对照几个场景,能看出清理范围受哪些参数影响,也能把「预览」和「已经清理」区分开来。命令名字很短,真正要核对的是执行前后有哪些路径会被碰到。

-n 会动文件吗?

不会。脚本在系统临时目录新建仓库,提交 .gitignore 和 tracked.txt,再放入 scratch.txt、目录 scratch-dir/nested.txt,以及规则 cache/ 忽略的 cache/data.bin。预览输出如下:

git clean -nd:
Would remove scratch-dir/
Would remove scratch.txt

-d 让预览把未跟踪目录也纳入;不加它时,Git 通常不会清理未跟踪目录。目录项按目录显示,不会逐个列出里面的文件。-n 是 dry run,适合先确认范围,不能当作已完成清理的证据。文件是否已被 Git 跟踪也会影响结果:这里的 tracked.txt 已提交,所以不会出现在候选中。若还有已暂存的新增文件,建议另看 git status --short,不要把它与 clean 的未跟踪候选混为一谈。

忽略目录为什么没出现?

默认的 git clean 不处理忽略规则命中的路径。对照实验再加 -x,候选里出现了 cache/:

git clean -ndx:
Would remove cache/
Would remove scratch-dir/
Would remove scratch.txt

-x 会把被忽略的文件也算进候选。清理构建缓存时这可能正合适;仓库里若把本地配置或数据目录列进 .gitignore,同一个开关就可能扩大到不该动的内容。忽略状态只是 Git 对路径的分类,不能说明里面的数据可以重建。还要区分 -X:它针对被忽略的文件,而 -x 会扩大到所有未跟踪项,包括本来会被忽略规则排除的路径。两者不是大小写不同的同义写法。

预览确认后怎么执行?

在同一临时仓库里运行 git clean -fd 后,普通未跟踪文件和目录消失,状态输出为空;忽略项仍存在。随后再运行 git clean -fdx,忽略目录才被删除。-f 是实际执行所需的强制选项,-d 允许移除未跟踪目录;预览与执行的选项应保持一致,别预览一组、执行另一组。-n 本身只是把拟执行的删除列出来,并不锁定工作区;预览后若又生成或修改文件,真正执行时遇到的内容可能已经不同。多模块仓库里还可以先切到目标子目录再运行,但要确认当前目录位置;误把清理命令从仓库根目录执行,覆盖范围会比预想的大。预览项出现得多时,先停下来读完整输出,不要只凭第一行判断。

另一个常见误区是把 git clean 当成 git reset 的替代品。前者面向未跟踪路径,后者处理索引或工作区状态;已经跟踪的文件不会因为出现在差异列表里就成为 clean 的目标。实验中提交的 tracked.txt 留在仓库,两个 clean 命令都没有提到它。若目的只是撤回已跟踪文件上的编辑,应先确认对应操作,不要用扩大清理范围的参数碰运气。

git clean -nd   # 预览未跟踪文件与目录
git clean -fd    # 确认后清理同一范围
git clean -ndx  # 预览时也包含忽略项

脚本记录了 git status --short --untracked-files=all 的结果:第一次清理后为 (clean),cache/data.bin 仍存在;第二次清理后状态仍为 (clean),该文件不存在。状态干净只表示 Git 不再列出变化,并不证明刚才删掉的内容无用。清理目录若包含唯一副本,Git 也不会替它兜底。我会把带 -x 的清理留给临时仓库或明确可再生的目录,先预览,再执行。验证脚本是 tools/verify-tools-git-clean-preview.py,完整输出在同名 .log。

    🤞 分享