问题描述
在尝试恢复旧项目时,有时我必须四处寻找旧的 Nixpkgs 提交才能开始工作。
例如,我的大部分 shell.nix
文件都是这样开头的,
{pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
# ...
}
这将从当前 channel 指向的提交中导入所有表达式,但是一段时间后,发生了太多更改,我的项目将不再构建;那么我将不得不找到一个仍然有效的提交,然后从那里开始。
$ nix-shell --arg pkgs \
> 'import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/0c0fe6d85b92c4e992e314bd6f9943413af9a309.tar.gz") {}'
如果我当时能从频道中保存工作提交,并且在以后需要时可以回退到一些可靠的东西,那可能是最好的。
解决方法
>= nixos 20.09
nix-shell -p nix-info --run "nix-info -m"
- 系统:
"x86_64-linux"
- 主机操作系统:
Linux 5.9.15,NixOS,20.09.2344.a3a3dda3bac (Nightingale)
# channel-commit - 多用户?:
yes
- 沙盒:
yes
- 版本:
nix-env (Nix) 2.3.9
- channels(root):
"nixos-20.09.2344.a3a3dda3bac"
# channel-commit - 频道(用户):
"nixos-20.09.2152.e34208e1003"
# 频道提交 - nixpkgs:
/nix/var/nix/profiles/per-user/root/channels/nixos
检查结尾,例如a3a3dda3bac
在 NixOS history 中,例如 release 20.09
我不会将 pkgs ? import <nixpkgs> {}
用于开发与您正在运行的当前系统无关的环境
- 改为导入,例如在
let
区域通过变量
用于开发环境:
# nix-shell shell_test.nix --argstr commitNixpkgs "0c0fe6d85b92c4e992e314bd6f9943413af9a309 --show-trace
{pkgs ? import <nixpkgs> {},commitNixpkgs ? "0c0fe6d85b92c4e992e314bd6f9943413af9a309" ; ref ? "refs/heads/nixpkgs-unstable",rev ? "502845c3e31ef3de0e424f3fcb09217df2ce6df6",...}:
let
nixPkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/${commitNixpkgs}.tar.gz") {config= { allowUnfree = true ; } ;} ;
# https://channels.nix.gsc.io/
# git ls-remote https://github.com/nixos/nixpkgs | grep unstable
# or via fetchGit
nixPkgs_fG = import (builtins.fetchGit {
name = "nixpkgs-unstable";
url = "https://github.com/nixos/nixpkgs-channels.git";
ref = ${ref}; #"refs/heads/nixpkgs-unstable";
rev = ${rev}; #"502845c3e31ef3de0e424f3fcb09217df2ce6df6";
}) {config= { allowUnfree = true ; } ; } ;
# nix-shell -p nix-prefetch-git --run ' nix-prefetch-git https://github.com/nixos/nixpkgs.git refs/heads/nixos-unstable '
in
...
,
要扩展 NixOS 讨论主题 How to see what commit is my channel on? 中提供的答案:
注意:在尝试任何这些方法之前,请确保您向正确的用户发出命令!
无论哪种方式都不会造成伤害,但是如果您使用 NixOS 和 manage things declaratively(在重建系统时作为 root
),那么您可能会得到与您需要的不同的提交哈希。 (特别是如果您曾经在没有 nix-channel --update
的情况下发布过 sudo
,这也会为您的 用户个人资料设置一个频道。)
方法 0
根据 NixOS wiki's Nix channels entry,“a channel 是 Nixpkgs 中最新“经过验证的”git 提交的名称。也就是说,在任何给定时间,通道指向 the Nixpkgs git repository on Github 中的特定提交; 每个 Nix 频道实际上是 repo 中的一个 git 分支:
$ nix-channel --list
nixos https://nixos.org/channels/nixos-20.09
----- -----------
(name) (branch-name)
# |
# V
# https://github.com/NixOS/nixpkgs/tree/<branch-name>
# i.e. https://github.com/NixOS/nixpkgs/tree/nixos-20.09
因此,如果您只是在 nix-channel --update
之前执行了 nix-shell
,并且它有效,只需在 Nixpkgs repo 的通道分支中查找最后一次提交。
方法一
"Chapter 12. Channels" of the Nix manual 提到 nix-channel --update
"默认情况下使每个通道的 Nix 表达式的联合可用于 nix-env
操作(通过符号链接 ~/.nix-defexpr/channels
)”。
要查看 ~/.nix-defexpr/channels
符号链接指向的位置,请使用 readlink -f
跟随符号链接链并将其与 ls
结合以直奔主题:
$ ls -l $(readlink -f ~/.nix-defexpr/channels)
total 6432
dr-xr-xr-x 2 root root 4096 Jan 1 1970 ./
drwxrwxr-t 8191 root nixbld 6569984 Feb 9 15:51 ../
lrwxrwxrwx 1 root root 78 Jan 1 1970 nixos -> /nix/store/k737c631q19n54fhjmnf68frg5dar14w-nixos-20.09.3009.8e78c2cfbae/nixos/
lrwxrwxrwx 1 root root 60 Jan 1 1970 manifest.nix -> /nix/store/a5wl1fri2sasnsb1i5zscni5h7kjg7d6-env-manifest.nix
我的频道名称是 nixos
,它指向
/nix/store/k7..4w-nixos-20.09.3009.8e78c2cfbae/nixos/
-----------
^
|
channel-commit
并且提交哈希就在 MAJOR.MINOR.PATCH version number 之后。
旁白:要为问题中的 fetchTarball
构建 tarball URL,请使用以下模板:
https://github.com/<user>/<repo>/archive/<full-or-abbr-commit-hash>.tar.gz
例如:
https://github.com/NixOS/nixpkgs/archive/8e78c2cfbae.tar.gz
或者,单击绿色的“代码”按钮,然后复制“下载 ZIP”链接的 URL(并将 zip
扩展名更改为 tar.gz
)。
有趣的事实:如果您在方法 1 之前执行了 nix-channel --update
,那么 URL https://github.com/NixOS/nixpkgs/tree/<branch-name>
和 https://github.com/NixOS/nixpkgs/tree/<channel-commit>
将指向 {{3} } 回购。