go mod tidy 不会删除空目录,因为它只管理 go.mod 和 go.sum 中声明的依赖,不触碰磁盘上已下载但未引用的模块目录,即使这些目录为空。

为什么 go mod tidy 不会删空目录
Go 的模块依赖默认存放在 $GOPATH/pkg/mod(或 GOPATH 未设置时的 $HOME/go/pkg/mod),go mod tidy 只管理 go.sum 和 go.mod 中声明的依赖,它从不触碰磁盘上已下载但未被引用的模块目录——哪怕那些目录里只剩一个空 cache 子目录或完全没文件。这些残留空文件夹越积越多,尤其在频繁切换分支、试验不同依赖版本后,pkg/mod/cache/download 和 pkg/mod/xxx@xxx 下会出现大量无用目录。
用 find + rmdir 安全清理空目录
直接递归 rm -rf 风险太大,可能误删正在使用的模块。稳妥做法是只删「真正为空」的目录(不含文件、不含子目录、不含隐藏文件)。Linux/macOS 下可用:
find $GOPATH/pkg/mod -depth -type d -empty -exec rmdir {} +
关键点:
-
-depth:自底向上遍历,避免父目录先被删导致子目录路径失效 -
-type d:只匹配目录 -
-empty:严格要求目录内无任何条目(包括.gitkeep、.DS_Store等隐藏文件) -
rmdir:只删空目录,比rm -rf安全;遇到非空目录会跳过,不报错
Windows 用户可用 PowerShell 替代:Get-ChildItem -Path "$env:GOPATH\pkg\mod" -Recurse -Directory | Where-Object { (Get-ChildItem $_.FullName -Force | Measure-Object).Count -eq 0 } | ForEach-Object { Remove-Item $_.FullName }
避开 cache 目录和 tmp 类临时区
pkg/mod/cache 下的目录结构特殊,有些看似空实则含元数据(如 download/xxx/@v/list),盲目清理会导致下次 go get 重新下载索引。建议排除:
立即学习“go语言免费学习笔记(深入)”;
-
pkg/mod/cache整个路径 -
pkg/mod/tmp(Go 内部临时解压区) - 任何以
.lock或.git结尾的目录(虽少见,但防万一)
加过滤后的安全命令:
find $GOPATH/pkg/mod -depth -type d -not -path "*/cache/*" -not -path "*/tmp/*" -empty -exec rmdir {} +
封装成可复用的脚本并设为 alias
把逻辑写进 shell 脚本比每次敲命令更可靠。新建 go-clean-mod.sh:
#!/bin/sh
MOD_ROOT="${GOPATH:-$HOME/go}/pkg/mod"
if [ ! -d "$MOD_ROOT" ]; then
echo "mod root not found: $MOD_ROOT" >&2
exit 1
fi
find "$MOD_ROOT" -depth -type d \
-not -path "*/cache/*" \
-not -path "*/tmp/*" \
-empty -exec rmdir {} + 2>/dev/null
然后加到 shell 配置中:alias go-clean-mod='sh ~/go-clean-mod.sh'
运行 go-clean-mod 即可。注意:该脚本不处理 Windows,也不兼容 GOBIN 或多模块工作区下的 vendor 模式路径——那些场景需单独判断 go env GOMODCACHE 输出的实际路径。
真正要小心的是 go mod download -x 过程中产生的中间目录,它们可能短暂为空但正被 Go 工具链占用;所以最好在没有 go 命令运行时执行清理,且别加 -delete 之类激进选项。


















