Open edolstra opened 4 years ago
is there any way to make Nix do the copying with hardlinks instead?
https://nixos.org/manual/nix/stable/command-ref/conf-file.html#conf-auto-optimise-store does that with files already found in the nix store. So, it won't hardlink them with those in your CWD, but if it has to copy the dirty flake once and again, at least that won't mean triplicated storage. "Only" ~duplicated.
In newer version of Linux, you can reflink between vfs barriers as long as it's the same superblock. Btrfs for example supports this but ZFS does not.
On my machine (NixOS 23.05, linux 6.5.5) if source directory and /nix/store are on the same Btrfs filesystem, data is not shared among copies after running nix develop
, thus taking space. btrfs filesystem du
shows exclusive data for each copy.
It would be nice if it worked, lowering the severity of the problem at least for Btrfs users (even though metadata of such copies still takes up space).
@AleXoundOS note that reflinking is something an application must choose to do; it is not the default. (IMO it really should be but that's a topic for a different project.)
I don't think it's worth spending time on this at this point though as it's much more important to push https://github.com/NixOS/nix/pull/6530 forward. After that's done, reflinking would be an extremely minor optimisation; probably not signficant enough to be worth considering.
This issue has been mentioned on NixOS Discourse. There might be relevant details there:
https://discourse.nixos.org/t/using-nix-shells-without-polluting-repositories/37362/6
Looks like this is not getting anywhere for the moment, how about allowing listing necessary files in the flake?
E.g. the attribute files
would be an optional list of relative paths, and if it exists, only those paths get copied. Directories get recursively copied.
To make it more dev-friendly, the list could be globs instead of paths, so that you can include or exclude.
If you don't use IFD, can you just first load all nix files imported by flake.nix into memory and eval them then?
Can someone tell me why you'd need to copy directories flakes reside in into the store if self is not used as a path? E.g. not used at all or just an attr like self.packages.x86_64-linux.default
. It could be alright for self + /pkgs/foo.nix
but that doesn't justify copying every single file, does it?
What about simple devshell flakes? Why are their directories copied into the store? It's just one nix file that doesn't use ./.
or self
.
I personally use path:///home/axel/.nix-config
just so I don't have to commit every single time I try a new change.
path://
doesn't copy anything into the store, right? Could there be a better way to bypass Git?
Edit: nevermind the last part, I thought path://
was going away. Anyways, could .git
be copied or just read while evaluating? It ignores files from .gitignore and only contains committed files do it's perfectly pure. Can someone explain why it needs copying?
Edit 2: If something like a files
attribute or .flakeignore
were to be added could derivations use something like bind mounts or links to not have to copy anything to the store?
I personally use
path:///home/axel/.nix-config
just so I don't have to commit every single time I try a new change.path://
doesn't copy anything into the store, right? Could there be a better way to bypass Git?
You don't have to commit every time you make a change with the git fetcher ("tree is dirty" is just a warning) and flakes are always copied to the store, even with path URLs. If that doesn't work for you, have a shell.nix until #6530 is complete.
Currently flakes are evaluated from the Nix store, so when using a local flake, it's first copied to the store. This means that
is a lot slower than the non-flake alternative
Ideally, we would copy the flake to the store only when its
outPath
attribute is evaluated. However, we also need to ensure that it's not possible to access untracked files (i.e. we need to check every file againstgit ls-files
).