1

When trying to revive old projects, sometimes I have to fish around for older Nixpkgs commits to get things started.

For example, most of my shell.nix files start like this,

{pkgs ? import <nixpkgs> {} }:

pkgs.mkShell {
  # ...
}

that would import all expressions from the commit where the current channel points to, but after some time, there have been so many changes that my project won't build anymore; then I will have to find a commit that still does, and go from there.

$ nix-shell --arg pkgs \
> 'import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/0c0fe6d85b92c4e992e314bd6f9943413af9a309.tar.gz") {}'

It would probably be the best if I could just save the working commit from the channel at the time, and have something solid to fall back to when needed later.

toraritte
  • 4,130
  • 3
  • 26
  • 43

2 Answers2

2

>= nixos 20.09

nix-shell -p nix-info --run "nix-info -m"
  • system: "x86_64-linux"
  • host os: Linux 5.9.15, NixOS, 20.09.2344.a3a3dda3bac (Nightingale) # channel-commit
  • multi-user?: yes
  • sandbox: yes
  • version: nix-env (Nix) 2.3.9
  • channels(root): "nixos-20.09.2344.a3a3dda3bac" # channel-commit
  • channels(user): "nixos-20.09.2152.e34208e1003" # channel-commit
  • nixpkgs: /nix/var/nix/profiles/per-user/root/channels/nixos

check the ending e.g. a3a3dda3bac in the NixOS history like release 20.09


I would not use pkgs ? import <nixpkgs> {} for developing environments which are not tied to the current system you are running on

  • instead import e.g. in let area via a variable

for developing environments:

# 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 
  ...    
InLaw
  • 2,026
  • 2
  • 16
  • 28
0

To expand on the answer provided in the NixOS discourse thread How to see what commit is my channel on?:

Note: Before trying any of these methods, make sure that you are issuing commands with the right user!
No harm done either way, but if you are on NixOS and manage things declaratively (as root when rebuilding the system) then you might get a different commit hash than what you need. (Especially if you ever issued nix-channel --update without sudo, which will set up a channel for your user profile as well.)

Method 0

According to the NixOS wiki's Nix channels entry, "a channel is a name for the latest "verified" git commits in Nixpkgs". That is, at any given time, a channel points to a specific commit in the Nixpkgs git repository on Github; each Nix channel is actually a git branch in the repo:

$ 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

So if you just executed nix-channel --update before nix-shell, and it works, just look up the last commit in the channel branch in the Nixpkgs repo.

Method 1

"Chapter 12. Channels" of the Nix manual mentions that nix-channel --update "makes the union of each channel’s Nix expressions available by default to nix-env operations (via the symlink ~/.nix-defexpr/channels)".

To see where the ~/.nix-defexpr/channels symlink points to, use readlink -f to follow the symlink chain and combine it with ls to get straight to the point:

$ 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

My channel's name is nixos, and it points to

/nix/store/k7..4w-nixos-20.09.3009.8e78c2cfbae/nixos/
                                   -----------
                                        ^
                                        |
                                   channel-commit

and the commit hash is right after the MAJOR.MINOR.PATCH version number.


Aside: To construct the tarball URL for fetchTarball in the question, use the following template:

https://github.com/<user>/<repo>/archive/<full-or-abbr-commit-hash>.tar.gz

For example:

https://github.com/NixOS/nixpkgs/archive/8e78c2cfbae.tar.gz

Alternatively, click the green "Code" button, and copy the URL of the "Download ZIP" link (and change the zip extension to tar.gz).


Fun fact: if you did nix-channel --update before method 1, then URLs https://github.com/NixOS/nixpkgs/tree/<branch-name> and https://github.com/NixOS/nixpkgs/tree/<channel-commit> will point to the same place in the Nixpkgs repo.

toraritte
  • 4,130
  • 3
  • 26
  • 43
  • There are much easier ways to find the channel version. You can use `nix-instantiate --eval -A 'lib.version' ''` or just start a `nix repl ''` and type `lib.version` at the prompt. This will print something like `"20.09.3087.2394284537b"`. – Henri Menke Feb 11 '21 at 20:05
  • @HenriMenke These are not the same (and to get the same commit as with `lib.version`, probably the shortest command would be `nixos-version`). Just did a `git show` on both, and the version commit hash is a month older than the one on my main channel. Plus, there could multiple channels. On the other hand, being a novice when it comes to Nix/NixOS/Nixpkgs, I'm quite sure that there must be a shorter method. – toraritte Feb 11 '21 at 22:26
  • `nixos-version` only works on NixOS, obviously. When you run `nix-instantiate --eval -A 'lib.version' ''` you get the commit that the `nixpkgs` channel is on. If you have another channel, e.g. `nixpkgs-unstable` just use that between the angle brackets. There should also be no mismatch between `lib.version` and the path in the Nix store: http://dpaste.com/BTN64D5SL (expires in 10 days) – Henri Menke Feb 12 '21 at 10:21
  • About `nixos-version`: ; totally forgot that it is just on NixOS:) Thanks also for the one-liner (just learned another thing) but I still get different results on my end. Do you get the same results after you do `nix-channel --update`? Could this be a NixOS-specific thing? – toraritte Feb 12 '21 at 13:27
  • https://chat.stackoverflow.com/rooms/228633/how-to-get-the-nix-channel-commit-hash – toraritte Feb 12 '21 at 13:34
  • On NixOS the situation is a bit more tricky because users can have different channels than the system. Alas, I can't say much about that because I'm using flakes to get around the headache that channels are. You can check whether the `pkgs.path` attribute points to the same directory as the `~/.nix-defexpr/channels/nixpkgs` symlink, i.e. `nix-instantiate --eval -A 'pkgs.path' ''`. Example: http://dpaste.com/339BV4UN2 (expires in 10 days) – Henri Menke Feb 12 '21 at 14:29