I had trouble working out how to pin the nixpkgs registry entry to a release channel. I’m posting it here in case anyone else finds it helpful.
On my system, I want the nixpkgs flake to refer to the nixos-21.05 channel (flake url: github:NixOS/nixpkgs/nixos-21.05). But I want this channel to be pinned to a known commit. I want to be able to update this manually.
In order to achieve this, I use the following steps:
Starting off, I don’t have any user registry entries:
$ nix registry list
....
global flake:nixpkgs github:NixOS/nixpkgs
...
At this point, the nixpkgs flake will refer to the master branch in github:NixOS/nixpkgs (which is currently immediately before the 21.11 release):
$ nix eval nixpkgs#lib.version
"21.11pre-git"
First, you need to add an override to make nixpkgs refer to the nixos-21.05 branch:
$ nix registry add nixpkgs github:NixOS/nixpkgs/nixos-21.05
$ nix registry list
user flake:nixpkgs github:NixOS/nixpkgs/nixos-21.05
...
global flake:nixpkgs github:NixOS/nixpkgs
...
You then need to pin github:NixOS/nixpkgs/nixos-21.05:
$ nix registry pin github:NixOS/nixpkgs/nixos-21.05
$ nix registry list
user flake:nixpkgs github:NixOS/nixpkgs/nixos-21.05
user github:NixOS/nixpkgs/nixos-21.05 github:NixOS/nixpkgs/1e5c35dfbc8e0ad8c35aa1a6446f442ca1ec5234
...
global flake:nixpkgs github:NixOS/nixpkgs
...
Now, the nixpkgs flake will refer to this known-good commit on the nixos-21.05 branch:
$ nix eval nixpkgs#lib.version
""21.05pre-git""
When you want to bump the pin to the latest version of nixos-21.05, you can use the following command:
Note that you must not accidentally pin the nixpkgs flake. DO NOT DO THIS:
$ nix registry pin nixpkgs
$ nix registry list
user github:NixOS/nixpkgs/nixos-21.05 github:NixOS/nixpkgs/1e5c35dfbc8e0ad8c35aa1a6446f442ca1ec5234
user flake:nixpkgs github:NixOS/nixpkgs/9fcf2a8a2cb0f5b78edc8ec7ca877240e7fe3009
...
global flake:nixpkgs github:NixOS/nixpkgs
...
$ nix eval nixpkgs#lib.version
"21.11pre-git"
You can see that here the nixpkgs flake is now pointing back at the master branch. It is unfortunate that Nix doesn’t just “do the right thing” here.
When you want to make the nixpkgs flake point a more recent release of NixOS (the next version will probably be 21.11), you can use the following command:
$ nix registry add nixpkgs github:NixOS/nixpkgs/nixos-21.11
$ nix registry pin github:NixOS/nixpkgs/nixos-21.11
$ nix registry list
user github:NixOS/nixpkgs/nixos-21.05 github:NixOS/nixpkgs/1e5c35dfbc8e0ad8c35aa1a6446f442ca1ec5234
user flake:nixpkgs github:NixOS/nixpkgs/nixos-21.11
user github:NixOS/nixpkgs/nixos-21.11 github:NixOS/nixpkgs/068984c00e0d4e54b6684d98f6ac47c92dcb642e
...
global flake:nixpkgs github:NixOS/nixpkgs
...
$ nix eval nixpkgs#lib.version
"21.11pre-git"
(Note that this won’t actually work until the nixos-21.11 branch has been created.)
I personally don’t like the global registry, with its imperative way of management.
Instead I remove the global registry and declaratively setup the user registry.
To remove the global registry, set the flake-registry option in nix.conf to an empty registry:
@kouakitaki’s post makes the nixpkgs flake point to the same commit used to build the system, but it requires inputs, which in turn requires
specialArgs = { inherit inputs; } in your nixpkgs.lib.nixosSystem call
outputs = { self, nixpkgs, ... }@inputs: in your flake.nix
If your /etc/nixos only has configuration.nix and no flake.nix (like mine), you can make the nixpkgs flake point to the same commit used to build the system with
nix.registry.nixpkgs.to = { type = "path"; path = "${pkgs.path}"; };
This will add a system override for flake:nixpkgs pointing to your nixos channel:
$ nix registry list | grep flake:nixpkgs
system flake:nixpkgs path:/nix/store/wz4m5rihmc3wszckma7zd743bm4jaywx-nixos
global flake:nixpkgs github:NixOS/nixpkgs/nixpkgs-unstable
Now you can use nix shell nixpkgs\#foo -c (like nix run nixpkgs.foo -c before flakes) instead of nix-shell -p foo --run and get the same versions as the rest of your system!