go list -m all 能看到当前解析出的全部依赖,输出当前模块及其所有直接/间接依赖的路径和版本,带 // indirect 标记的是传递性引入的依赖,不带标记的是代码中显式 import 的包。

go list -m all 能看到当前解析出的全部依赖
执行 go list -m all 是最直接的方式,它会输出当前模块及其所有直接/间接依赖的路径和版本。输出中带 // indirect 标记的是未被直接 import、仅因传递性引入的依赖;不带标记的是你代码里显式 import 过的包。
注意:这个命令反映的是「当前 go.mod + 本地缓存」下的解析结果,不是历史快照。如果刚执行过 go mod tidy 或 go get,结果会更新;但不会告诉你某个依赖是哪次提交加进来的。
- 想快速定位某依赖是否为间接引入,用
go list -m -f '{{.Indirect}}' github.com/sirupsen/logrus - 想看依赖树结构(谁依赖了谁),用
go list -m -json all | jq '.配合jq工具展开嵌套关系(需提前安装) - 输出里出现伪版本(如
v0.0.0-20230101000000-abcdef123456),说明该依赖尚未打 tag,Go 自动按 commit 时间+哈希生成版本号
go mod graph 输出依赖关系图
go mod graph 打印的是模块间 import 关系的有向图,每行格式为 A B,表示模块 A 依赖模块 B。它不显示版本号,但能暴露隐式依赖链——比如你没直接 import golang.org/x/net,但 github.com/gin-gonic/gin 依赖它,这条边就会出现在输出里。
常见误判点:输出里重复出现同一模块对同一依赖的多条边,不代表冲突,而是不同路径都经过该节点;真正要警惕的是环形路径(虽然 Go 编译器会在 build 阶段报错,但 go mod graph 不做环检测)。
- 过滤特定依赖:
go mod graph | grep 'golang.org/x/text' - 统计某模块被多少其他模块引用:
go mod graph | awk '{print $2}' | grep 'golang.org/x/sys' | wc -l - 输出过大时建议重定向到文件:
go mod graph > deps.dot,再用 Graphviz 可视化
git log 结合 go.mod 变更追踪版本演进
Go 没有内置的依赖变更日志,但 go.mod 文件本身是文本,且每次 go get 或 go mod tidy 都会修改它。所以最可靠的演进记录来自 git 提交历史。
关键操作不是看单次 diff,而是用 git blame go.mod 定位某行 require 是谁、什么时候加的;再配合 git log -p -S 'github.com/urfave/cli' go.mod 查找该依赖首次出现和后续升级的所有提交。
- 升级依赖时,
go get默认只改go.mod中对应行,不碰其他依赖——这是干净演进的前提 - 如果团队多人同时修改
go.mod,合并冲突后务必运行go mod tidy再提交,否则可能残留无效 require - 不要手动编辑
go.sum:它的校验和由 Go 工具自动生成,手改会导致go build失败并提示checksum mismatch
go mod why 解释某个依赖为何存在
当你发现一个陌生依赖出现在 go list -m all 输出里,又不确定它从哪来,go mod why <module></module> 就是解谜钥匙。它会尝试找出一条最短 import 路径,说明为什么这个模块被拉进来。
例如 go mod why golang.org/x/crypto 可能返回:
# golang.org/x/crypto<br>github.com/gorilla/sessions<br>github.com/gorilla/securecookie<br>golang.org/x/crypto——说明是 sessions 包通过 securecookie 间接引入的。
- 如果返回
(main module does not need it),说明该模块目前未被任何 import 触发,可能是之前 tidy 未清理干净,可手动go mod tidy - 对私有模块(如
git.example.com/internal/utils)同样有效,前提是已配置GOPRIVATE - 它不保证路径唯一:MVS 算法可能选不同版本,
why只展示当前解析出的那一条
真正难的不是查“现在有什么依赖”,而是判断“这个依赖能不能删”或“升级会不会破坏”。这需要结合 go mod why 看调用链、go list -f '{{.Imports}}' ./... 看实际 import 语句、以及单元测试覆盖率——工具只给线索,决策还得靠人。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











