NixOS / nix

Nix, the purely functional package manager
https://nixos.org/
GNU Lesser General Public License v2.1
12.75k stars 1.52k forks source link

When creating the first generation of a profile, also create an empty zeroth generation #1807

Open copumpkin opened 6 years ago

copumpkin commented 6 years ago

The very first nix-env operation isn't currently reversible. Say I have a fresh Nix install and I write something like nix-env -iA nixpkgs.gitFull. Before running that command, I didn't have git in scope, and afterwards, I do. If I nix-env --rollback to get back to no git, I get this error message:

error: no generation older than the current (1) exists

Which makes sense because there was no zeroth generation. However, from a UX perspective, there is an "implicit" zeroth generation, meaning the profile hasn't been created yet. It seems like Nix, when creating the first generation of a profile, could also sneak in an empty zeroth generation to make rollbacks to emptiness work seamlessly.

Also, we'd probably want to disallow an empty system profile 😄 but for user profiles, this seems like the right behavior.

stale[bot] commented 3 years ago

I marked this as stale due to inactivity. → More info

stale[bot] commented 2 years ago

I closed this issue due to inactivity. → More info

iFreilicht commented 1 year ago

I agree, this would be a very useful and logical feature. I'm wondering a bit about the semantics, though. Should it just be an empty derivation? Or a call to nixpkgs.buildEnv with name="empty-profile" and "paths=[ ]"?

I would argue the latter is more useful, as it makes the output of nix profile history and nix profile diff-closures etc. more useful for the first generation. All the default cruft is installed in the 0th generation, so the 1st one only lists what you actually added manually.

nixos-discourse commented 1 year ago

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/flakes-as-a-unified-format-for-profiles/29476/1

iFreilicht commented 3 months ago

For anyone who faces this problem and just wants a quick solution:

ln -snf $(nix-build --expr '(import <nixpkgs> {}).runCommand "empty-profile" {} "mkdir -p $out"') "$(dirname $(readlink ~/.nix-profile))/profile-0-link"

Running this once creates an empty zeroth generation, after which you can roll back to it and commands like nix profile diff-closures work just fine.

I also tried this out with 'with (import <nixpkgs> {}); buildEnv { name = "empty-profile"; paths = []; }' and added various things to paths, but that didn't significantly shorten the list of installed packages, and especially for the case of a rollback, it would be very confusing if the first "empty" generation actually contained anything.