Skip to content

Allow garbage-collecting a closure#15236

Merged
Ericson2314 merged 1 commit into
NixOS:masterfrom
lisanna-dettwyler:gc-closure-2
Apr 10, 2026
Merged

Allow garbage-collecting a closure#15236
Ericson2314 merged 1 commit into
NixOS:masterfrom
lisanna-dettwyler:gc-closure-2

Conversation

@lisanna-dettwyler

@lisanna-dettwyler lisanna-dettwyler commented Feb 14, 2026

Copy link
Copy Markdown
Contributor

Add option --skip-alive to nix store delete

nix store delete --recursive --skip-alive is morally equivalent to

for validPath in $(nix path-info --recursive foo); do
  nix store delete "$validPath" || true
done

Also adds utility function nix dev-env-path to facilitate use with devShells. will be split off into separate PR

Resolves #7239

Motivation

This is the most requested unresolved feature in Nix. (https://github.com/NixOS/nix/issues?q=is%3Aissue%20state%3Aopen%20sort%3Areactions-%2B1-desc)

Context

#7239

Replaces #8417 because the author appears to have stopped working on it years ago.

This is a separate command to avoid the pitfall of nix store gc $(getSomePaths) resolving to nix store gc, which would unintentionally GC the entire store.


Add 👍 to pull requests you find important.

The Nix maintainer team uses a GitHub project board to schedule and track reviews.

@github-actions github-actions Bot added documentation new-cli Relating to the "nix" command with-tests Issues related to testing. PRs with tests have some priority store Issues and pull requests concerning the Nix store labels Feb 14, 2026
@lisanna-dettwyler lisanna-dettwyler force-pushed the gc-closure-2 branch 2 times, most recently from 86012d3 to 2f34a72 Compare February 14, 2026 06:15
@lisanna-dettwyler lisanna-dettwyler changed the title Allow garbage-collecting whithin a closure Allow garbage-collecting within a closure Feb 14, 2026
@lisanna-dettwyler lisanna-dettwyler force-pushed the gc-closure-2 branch 3 times, most recently from 8f3db57 to 34bc281 Compare February 14, 2026 06:55
@lisanna-dettwyler lisanna-dettwyler marked this pull request as ready for review February 14, 2026 07:39
@lisanna-dettwyler lisanna-dettwyler force-pushed the gc-closure-2 branch 2 times, most recently from 6082386 to 38782d1 Compare February 16, 2026 18:48
@lisanna-dettwyler lisanna-dettwyler force-pushed the gc-closure-2 branch 4 times, most recently from e9bb1d4 to 1b5a1b2 Compare March 18, 2026 20:19
Comment thread tests/functional/gc-closure.sh Outdated
Comment thread src/libstore/gc.cc Outdated
Comment thread tests/functional/gc-closure.sh Outdated

@xokdvium xokdvium left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to me. Nice that we can hack it in without changing the actual worker protocol too much.

@Ericson2314

Copy link
Copy Markdown
Member

@roberth I am trying to remember the CLI guidelines. Should this be nix store delete --recursive? What other flavors of deleting things should we have?

@lisanna-dettwyler

lisanna-dettwyler commented Mar 25, 2026

Copy link
Copy Markdown
Contributor Author

@roberth I am trying to remember the CLI guidelines. Should this be nix store delete --recursive? What other flavors of deleting things should we have?

Maybe nix store delete --recursive --ignore-alive? Or is that too similar sounding to --ignore-liveness, which has the opposite effect?

@lisanna-dettwyler lisanna-dettwyler force-pushed the gc-closure-2 branch 3 times, most recently from 02002bb to 395130a Compare March 30, 2026 17:33
@lisanna-dettwyler lisanna-dettwyler changed the title Allow garbage-collecting within a closure Allow garbage-collecting a closure Mar 30, 2026
Comment thread src/libstore/gc.cc Outdated
Comment on lines +364 to +368
// This violates the convention that an empty `pathsToDelete` corresponds
// to the whole store, but deleting the whole store doesn't make sense,
// and `nix-store --delete` is a valid command that deletes nothing, so
// we need to keep it as-it-is.
return;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So basically we maintain the invariant that an added installable increases the number of candidates to try delete?
I agree it's the more expected and safer behavior.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right

input0=$(realpath "$TEST_ROOT/gc-root")
input1=$(nix build -f dependencies.nix input1_drv --no-link --print-out-paths)
input2=$(nix build -f dependencies.nix input2_drv --no-link --print-out-paths)
top=$(nix build -f dependencies.nix --no-link --print-out-paths)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related

Its implementation could drop the --no-link here.

No action required.

Comment thread src/libstore/daemon.cc Outdated

if (!options.pathsToDelete.empty() && options.action == GCAction::gcDeleteDead
&& !conn.protoVersion.features.contains(WorkerProto::featureGcClosure)) {
throw Error("Garbage collecting a closure requested but it is not supported by the negotiated protocol");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way I understand it, this is near-unreachable and only a nix-as-client logic error would trigger this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I don't think this is reachable currently and would only happen due to a future introduced logic error

Comment thread src/libstore/remote-store.cc Outdated
@lisanna-dettwyler lisanna-dettwyler force-pushed the gc-closure-2 branch 2 times, most recently from f882069 to 1f94c57 Compare April 10, 2026 19:28
Comment thread src/libstore/include/nix/store/gc-store.hh Outdated
Comment thread src/libstore/remote-store.cc Outdated
auto store = openStore();
auto & gcStore = require<GcStore>(*store);
options.action = dryRun ? GCOptions::gcReturnDead : GCOptions::gcDeleteDead;
options.pathsToDelete = GCOptions::WholeStore{};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, I like how it forces us to be explicit!

@lisanna-dettwyler lisanna-dettwyler force-pushed the gc-closure-2 branch 2 times, most recently from d1e26a4 to 5033d29 Compare April 10, 2026 21:21
Comment thread src/libstore/daemon.cc
Comment thread src/libstore/gc.cc
Comment thread src/libstore/gc.cc Outdated
Comment thread src/libstore/worker-protocol.cc Outdated
Comment thread src/libstore/remote-store.cc Outdated
Comment thread src/libstore/gc.cc Outdated
Comment thread src/libstore/gc.cc Outdated
This allows garbage collecting a closure.

`nix store delete --recursive --skip-alive` is morally equivalent to

```bash
for validPath in $(nix path-info --recursive foo); do
  nix store delete "$validPath" || true
done
```

Resolves NixOS#7239

Co-authored-by: Théophane Hufschmitt <theophane.hufschmitt@tweag.io>
Co-authored-by: Alexander Bantyev <balsoft@balsoft.ru>
Signed-off-by: Lisanna Dettwyler <lisanna.dettwyler@gmail.com>

@Ericson2314 Ericson2314 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All fixed now!

@Ericson2314 Ericson2314 enabled auto-merge April 10, 2026 23:08
@Ericson2314 Ericson2314 added this pull request to the merge queue Apr 10, 2026
Merged via the queue into NixOS:master with commit 9bec486 Apr 10, 2026
16 checks passed
@xokdvium xokdvium mentioned this pull request Jun 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation new-cli Relating to the "nix" command store Issues and pull requests concerning the Nix store with-tests Issues related to testing. PRs with tests have some priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Garbage collect a closure

5 participants