nix will pointlessly re-fetch registry entries if they are defined as store paths
Describe the bug
On my NixOS and nix-darwin machines I pin the system nixpkgs as nixpkgs so building stuff is faster, using nix.registry.nixpkgs.flake = nixpkgs; in my configuration.
/etc/nix/registry.json looks like so:
{"flakes":[{"exact":true,"from":{"id":"nixpkgs","type":"indirect"},"to":{"path":"/nix/store/cn1ag0zf4388i4s9ymx80hrqvma0p9qy-nixpkgs-src","rev":"36cc29d837e7232e3176e4651e8e117a6f231793","type":"path"}}],"version":2}
» nix registry list
system flake:nixpkgs path:/nix/store/cn1ag0zf4388i4s9ymx80hrqvma0p9qy-nixpkgs-src?rev=36cc29d837e7232e3176e4651e8e117a6f231793
........
and every time I use nix-command with flakes it pointlessly copies from the nix store to the nix store:
$ nix shell nixpkgs#hello
copying '/nix/store/cn1ag0zf4388i4s9ymx80hrqvma0p9qy-nixpkgs-src'
Steps To Reproduce
- Put the result of:
» nix eval --expr '<nixpkgs>' --impure
/nix/store/cn1ag0zf4388i4s9ymx80hrqvma0p9qy-nixpkgs-src
into /etc/nix/registry.json replacing my path above.
2. nix run nixpkgs#hello
Expected behavior
Should execute instantly because it avoids gratuitously copying a store path to the store.
nix-env --version output
» nix --version
nix (Nix) 2.10.3
however also reproduced on master:
co/nix - [master] » result/bin/nix --version
nix (Nix) 2.12.0pre20220921_f704c27
co/nix - [master] » result/bin/nix build nixpkgs#hello
copying '/nix/store/cn1ag0zf4388i4s9ymx80hrqvma0p9qy-nixpkgs-src
Additional context
Add any other context about the problem here.
Hmmm. So I've gone bughunting and I think I have found a part answer:
I think based on reading src/libfetchers/path.cc that it will possibly do this silly copying business if it is not a "store path", for instance, it will do the bad thing if you put /nix/store/6hmwry071zcdf5jphlrxgv3amgwwqc7n-nixpkgs/nixpkgs as you would get if it's a channel.
Not fully confident about this though: there's also checks that the name of the store path is "source". I wonder if that's related.
Are you sure that it's actually copying it, or do you just see the copying message?
Looking at the code, Nix prints the copying message, but then short-circuits if the path is a valid store path (which is still a problem because then we print a misleading message, but a slightly different one)
EDIT: nevermind, didn't see your previous message. Indeed the check for the source name is probably the cause of the copy.
I see the copying message, and it also takes a long time. The taking a long time leads me to believe it is being copied.
A fun thing is that /nix/store/xxx-blah/somesubdir is not considered a "store path" to Nix in this context, due to the subdirectory.
A fun thing is that /nix/store/xxx-blah/somesubdir is not considered a "store path" to Nix in this context, due to the subdirectory.
Yes. That's a gross approximation, but also required for purity (until/if ever #6530 lands) because relative paths (to the parent) will have a different meaning if you keep it as a subdir.
I think you can do /nix/store/xxx-blah?dir=somesubdir though, although I'm not 100% what the semantics are
Update from later: if you name your thing source, Nix will indeed not do the buggy behaviour. Rather odd.
Update from later: if you name your thing source, Nix will indeed not do the buggy behaviour. Rather odd.
But how did you rename it with nix.registry.nixpkgs.flake = nixpkgs;?