Saving expressions versions with nix-shell


I’m using direnv integration with nix-shell and it makes for a very nice workflow, and I always get the most recent version of all, say, my R packages whenever I do a system --update, which is good.

However it might happen that I leave the code for a couple of months (durnig which I might nix-collect-garbage), go back to it, get a flurry of new package versions, and something doesn’t work anymore.

In order to pinpoint what the problem is, it would be useful to know which was the version of each package that was installed (or rather, linked to the environment) through the default.nix during the last nix-shell invocation.

Is there a way to get that information, so that I can save it to a file and compare later? Something like:

default.nix run, 2018-11-26



it should be possible to “add a Garbage Collection root” or something like that
if i understand correctly this should prevent nix-collect-garbage removing the dep’s of your shell
nix-instantiate shell.nix --indirect --add-root $DIR/.nix-gc-roots/shell.drv ...

" --indirect and --add-root"

the comment here suggest this is no longer the case =/

The nix-shell options quoted above seem to be silently ignored today. I’m accomplishing something similar by parsing the output of nix show-derivation somewhat laboriously. It would be much nicer for nix tools to have some first-class way to reference a build-time closure.

& # nix-shell dependencies can be garbage collected any time now / persistent nix-shell envs

--indirect is now ignored as of 19477e8 this also no longer works as gcroot to the output is no longer created.

… +more scrips and hints in the above link


I think pinning nixpkgs directly in the default.nix may be a good solution?


There is also a wiki article for persistent direnv shells:


Great stuff, thanks.

I would still like to be able to generate the equivalent of a packrat.lock or requirement.txt file on each run, though.

Using these approaches it wouldn’t be easy to find which packages have changed versions (or would it?), while if I had a text file with the versions I would simply be a diff away from knowing which package is the culprit.

Something like nix-store -q for the current nix-shell environment, minus the default one for the user.


Fully persistent Nix shell (gist)
more discussion @ [Nix-dev] truly persistent nix-shell