当尝试恢复旧项目时,有时我不得不寻找旧的Nixpkgs提交来开始工作。
例如,我的大多数shell.nix
文件都是这样开头的,
{pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
# ...
}
将从当前通道指向的提交中导入所有表达式,但过了一段时间后,有太多的变化,我的项目将不再构建;然后我必须找到一个仍然有效的提交,并从那里开始。
$ 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"
- system:
"x86_64-linux"
- 主机os:
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 - channel (user):
"nixos-20.09.2152.e34208e1003"
# channel-commit - nixpkgs:
/nix/var/nix/profiles/per-user/root/channels/nixos
检查结尾,例如a3a3dda3bac
版本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讨论线程中提供的答案上展开如何查看我的通道在哪个提交上?:
注意:在尝试任何这些方法之前,请确保使用正确的用户发出命令!
这两种方式都没有害处,但是如果你在NixOS上并以声明方式管理事情(如在重建系统时使用root
),那么你可能会得到与你需要的不同的提交哈希值。(特别是如果您曾经发布nix-channel --update
而没有sudo
,这将为设置一个通道,您的用户配置文件。)
0
方法根据NixOS wiki的Nix channels条目,">achannel是最新的"已验证"的名称。git以Nixpkgs"格式提交。也就是说,在任何给定的时间,通道指向Github上Nixpkgs git存储库中的特定提交;每个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-shell
之前执行nix-channel --update
,并且它有效,只需在Nixpkgs的repo中查找通道分支中的最后一次提交。
方法1
,第12章。"渠道;Nix手册中提到,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版本号之后。
除了要构造问题中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"的网址。链接(并将zip
扩展名更改为tar.gz
)。
有趣的事实:如果你在方法1之前执行了nix-channel --update
,那么urlhttps://github.com/NixOS/nixpkgs/tree/<branch-name>
和https://github.com/NixOS/nixpkgs/tree/<channel-commit>
将指向Nixpkgs repo中的相同位置。
要获得完整的Git版本,运行cat /nix/var/nix/profiles/per-user/root/channels/nixpkgs/.git-revision; echo
(在EOF处没有换行符,因此我们需要添加一个换行符以避免提示符覆盖它)。如果该路径不存在,则可能使用了不同的通道名称,并且需要指定它。除非你绝对确定只有一个通道,否则不要使用glob。
然后运行nix-prefetch-url --type sha256 --unpack "https://github.com/nixos/nixpkgs/archive/$(cat /nix/var/nix/profiles/per-user/root/channels/nixpkgs/.git-revision).tar.gz"
获取SHA-256哈希值