大家好,我是Zack。
先说一个我自己出过的事:清项目垃圾文件,一条命令下去,把 .env 删了。里面是我本地跑项目的密钥配置,重建花了我快一个晚上。
从那以后我清垃圾只用 git,先看后删,三招用到现在没再出过事。今天把这三招写全,命令你直接抄。
老做法:find 一把梭
我原来的清法很原始:
find . -name "*.tmp" -o -name "*.log" | xargs rm
看着挺专业,其实两个坑。
第一个坑:这个命令没有「先看一眼」的环节,管道直通 rm,列出什么删什么。哪天目录里多了个 .env.bak,而你写的正则是 *.env*,它跟着陪葬。
第二个坑:.tmp 这种后缀根本盖不全。构建产物、缓存目录、编辑器交换文件,后缀五花八门,你写十条正则也未必盖住,还容易误伤。
我上周盘了下自己那个运营目录,垃圾文件有 246 个:181 个排队文本、41 个日志,混着 15 个 JSON。这种量,靠肉眼和正则清理,删一次心跳加速一次。
git 的思路:垃圾就是「没跟踪的文件」
git 眼里,你的项目分三类文件:已提交的、改过没提交的、以及既没提交也没加入跟踪的新文件。
第三类,基本就是垃圾文件待的地方:临时输出、日志、构建产物、本地配置。git 有现成命令管它们,叫 git clean。妙就妙在,它天生分两步——先预览,再删。
下面三招全部可以放心试,前两招纯只读。
第一招:git clean -nd,列出所有没跟踪的文件
git clean -nd
我拿一个演示仓库跑了,输出长这样:
Would remove .env
Would remove cache.tmp
Would remove debug.log
Would remove src/
-n 是 dry run(只列出,不真删),-d 连空目录一起列。看输出你就明白坑在哪了:.env 这种本地配置,git 也当成「没跟踪的新文件」。所以这一招只用来围观,看清你的目录里都躺了什么,别直接删。
参数这么记:-n = no,别动手;-d = directory,目录也算。
第二招:git clean -ndX,只看「该删的」垃圾
第一招的问题是把 .env 和真垃圾混在一起。解法是先写个 .gitignore,把你不想让 git 管的文件列进去:
.env
debug.log
cache.tmp
然后再跑:
git clean -ndX
输出变成:
Would remove .env
Would remove cache.tmp
Would remove debug.log
-X 大写,意思是只列被 .gitignore 忽略的文件。这一步就把「本地配置」和「垃圾」分开了:进了 .gitignore 的,才是你声明过的「可删项」。
这是我删垃圾的唯一依据:不是我觉得它是垃圾,是 .gitignore 说它是。
第三招:git clean -ndx,连忽略文件一起看
小写 -x,把忽略文件和普通未跟踪文件列一起,目录全扫一遍。适合隔了很久没清、想一次看全的场景。
删的时候把 -n 换成 -f(force,真动手):
git clean -fdX
我在演示仓库里真跑了一轮:删掉 3 个垃圾文件,.env 原样躺着,git status 里它还好好的。整个预览过程 0.1 秒内出结果。
我自己踩的一个坑:.gitignore 没提交,被自己清了
上面流程有个细节我不说你会踩。
我第一次演示时,.gitignore 刚写完,还没 git add 提交。跑 git clean -fd(注意没带 X)删普通垃圾时,git 把这个未跟踪的 .gitignore 也当垃圾删了。
后果很妙:ignore 文件没了,那三个被忽略的垃圾文件立刻「复活」,重新出现在未跟踪列表里。等于我清了一轮垃圾,顺手把清垃圾的规则也清了。
所以规矩就一条:.gitignore 写完马上提交进仓库。它是规则文件,不在「可删」名单里,就必须让 git 知道。
顺手查了下自己的博客仓库,真有存货
写这篇文章时我用第二招查了博客仓库(就是你现在能打开的这个站,410 个文件在 git 里),结果查出个更典型的问题:这仓库压根没有 .gitignore,.DS_Store(macOS 的桌面缓存文件,6KB)居然被 git 跟踪着,每次提交都可能带进去。
这种已经进了 git 的文件,git clean 管不了——它只删没跟踪的。补救两步:
git rm --cached .DS_Store
echo ".DS_Store" >> .gitignore
--cached 只把文件从 git 名册里除名,磁盘上不动它。然后提交这两个改动,以后它再生成,git 也不理。
目录压根不是 git 仓库怎么办
有人要问:我那个下载文件夹、桌面上的项目备份,不是 git 仓库,这三招用不了吧?
我的做法反着来:进目录,先 git init,git add -A,git commit,把它变成仓库,再清。提交这一步相当于给现在的状态拍了个快照,之后不管怎么删,git checkout . 一条命令全找得回来。
等于花 10 秒买个后悔药。桌面那种几百个文件的地方,我强烈建议这么干,比任何「回收站」都稳。
前后对比
老做法:写正则 → 列文件 → 肉眼核对 → 祈祷 → 删。正则改一次核对一轮,200 多个文件的目录下来十几分钟,而且「祈祷」那步没法优化。
新做法:.gitignore 声明可删项 → git clean -ndX 预览 → git clean -fdX 删除。三步,预览零点几秒,删错了……也不会错,因为名单是 .gitignore 说的,不是临时拍的脑袋。
更重要的是心路变化:以前删完要赶紧跑一遍项目看还能不能起来,现在删完不用跑,因为该在的都在。
两条原则,带得走
第一,预览和删除必须是两次命令。 任何「一步到位」的批量删除工具都别信,包括 find 接 xargs。你需要的不是快,是删之前那一眼。-n 这个 dry run 参数在 git、rsync 等一堆工具里都存在,养成先 -n 后 -f 的肌肉记忆,受益的不止清垃圾这一件事。
第二,「垃圾」的定义要写下来,别装在脑子里。 .gitignore 就是这个白纸黑字的定义。它提交进仓库后还有个附带好处:同事克隆你的项目,不会再问「这个 log 文件能不能删」。
最后
你目录里现在躺着多少垃圾?跑一下 git clean -nd,把数字留在评论区,我看看谁的最离谱。
有问题也留言,我看到都会回。