Nix Flakes:`git+file:.`与`path:.`的差异及相关技术疑问
Nix Flakes 路径类型与评估机制常见问题解答
问题1:git+file:.与path:.的差异是什么?
- 内容范围:
git+file:.仅包含Git已追踪(含暂存)的文件,严格遵循.gitignore规则忽略未追踪文件;path:.会包含当前目录下所有文件,不受Git状态和.gitignore约束。 - 哈希计算:
git+file:.的flake哈希基于Git仓库的提交/暂存状态生成;path:.的哈希则基于目录内所有文件的内容计算。 - 依赖依据:
git+file:.依赖Git的版本状态确定flake内容;path:.直接扫描本地文件系统的目录结构。
问题2:什么是self-contained(自包含)/hermetic evaluation(密封评估)?
自包含/密封评估指Nix评估flake时,所有输入依赖都被明确固定,完全不受外部环境(如全局配置、未追踪本地文件、动态网络内容)影响,确保只要输入确定,评估结果就完全一致,实现跨环境的构建可复现性。
问题3:git-flake评估是密封的,path-flake评估是否也具备密封特性?
path-flake的评估不具备严格的密封特性:
- path-flake会包含目录内所有文件,包括临时文件、编辑器缓存(如
*.swp)等未预期的内容,这类文件的变化会直接改变flake哈希,导致评估结果不稳定。 - 若目录内存在指向外部的符号链接,会引入外部依赖,进一步破坏评估的封闭性。
而git-flake仅关注Git追踪的内容,只要Git提交/暂存状态固定,评估结果就完全确定,是严格密封的。
问题4:nix build git+file:.是否拥有nix build path:.所没有的额外缓存机制?
是的。git+file:.的flake哈希与Git提交/暂存状态绑定,这个哈希可以和远程Git仓库的提交哈希对齐。在CI、其他机器等环境中,只要使用相同的Git提交构建,Nix可以直接复用远程缓存的构建结果,无需重新编译。
而path:.的哈希基于本地所有文件内容,临时文件、未追踪文件都会改变哈希值,几乎无法复用跨环境的缓存,仅能依赖本地构建缓存。
问题5:为何不将nix build .直接等同于nix build path:.,而要采用自动类型检测的设计?该设计试图解决什么问题?为何会存在后台自动执行git add这类特殊行为,而又可通过path:.轻易规避?
自动类型检测的核心目标是默认提供可复现的密封构建环境:
- 多数用户用Git管理项目,默认启用git-flake模式,能确保仅使用已追踪的代码,避免临时文件干扰构建结果,契合Flakes追求的确定性、可复现性核心设计目标。
- 后台自动
git add是为了处理flake.nix未暂存的场景:若修改了flake.nix但未暂存,Nix会自动暂存该文件,确保flake本身的修改被纳入评估范围,避免因flake文件未追踪导致评估结果不一致。但该行为存在争议,因此提供path:.作为灵活的规避选项,满足用户快速测试本地所有文件的需求。 - 不默认采用path模式,是因为path模式容易引入意外的外部依赖,破坏Flakes的可复现性,违背其设计初衷。
内容的提问来源于stack exchange,提问作者srghma
相关产品推荐
相关产品推荐

