diff --git a/doc/manual/nix-store.xml b/doc/manual/nix-store.xml
index 562a5439a..566c75bf3 100644
--- a/doc/manual/nix-store.xml
+++ b/doc/manual/nix-store.xml
@@ -404,6 +404,7 @@ error: cannot delete path `/nix/store/zq0h41l75vlb4z45kzgjjmsjxvcv1qk7-mesa-6.4'
name
+
@@ -586,12 +587,20 @@ query is applied to the target of the symlink.
Prints the SHA-256 hash of the contents of the
- store path paths. Since the hash is
+ store paths paths. Since the hash is
stored in the Nix database, this is a fast
operation.
+
+
+ Prints the garbage collector roots that point,
+ directly or indirectly, at the store paths
+ paths.
+
+
+
@@ -669,6 +678,18 @@ $ gv graph.ps
+Show every garbage collector root that points to a store path
+that depends on svn:
+
+
+$ nix-store -q --roots $(which svn)
+/nix/var/nix/profiles/default-81-link
+/nix/var/nix/profiles/default-82-link
+/nix/var/nix/profiles/per-user/eelco/profile-97-link
+
+
+
+
diff --git a/src/nix-store/help.txt b/src/nix-store/help.txt
index c4981168b..7576e3ef5 100644
--- a/src/nix-store/help.txt
+++ b/src/nix-store/help.txt
@@ -24,7 +24,6 @@ Operations:
--import: import a path from a Nix archive, and register as
valid
- --init: initialise the Nix database
--verify: verify Nix structures
--optimise: optimise the Nix store by hard-linking identical files
@@ -34,12 +33,14 @@ Operations:
Query flags:
--outputs: query the output paths of a Nix derivation (default)
- --requisites / -R: print all paths necessary to realise a path
- --references: print all paths referenced by the given path
- --referrers: print all paths directly refering to the given path
- --referrers-closure: print all paths (in)directly refering to the given path
- --tree: print a tree showing the dependency graph of the given paths
- --graph: print a dot graph rooted at given paths
+ --requisites / -R: print all paths necessary to realise the path
+ --references: print all paths referenced by the path
+ --referrers: print all paths directly refering to the path
+ --referrers-closure: print all paths (in)directly refering to the path
+ --tree: print a tree showing the dependency graph of the path
+ --graph: print a dot graph rooted at given path
+ --hash: print the SHA-256 hash of the contents of the path
+ --roots: print the garbage collector roots that point to the path
Query switches (not applicable to all queries):
diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc
index b95139309..e08908cd7 100644
--- a/src/nix-store/nix-store.cc
+++ b/src/nix-store/nix-store.cc
@@ -261,14 +261,13 @@ static void opQuery(Strings opFlags, Strings opArgs)
{
enum { qOutputs, qRequisites, qReferences, qReferrers
, qReferrersClosure, qDeriver, qBinding, qHash
- , qTree, qGraph, qResolve } query = qOutputs;
+ , qTree, qGraph, qResolve, qRoots } query = qOutputs;
bool useOutput = false;
bool includeOutputs = false;
bool forceRealise = false;
string bindingName;
- for (Strings::iterator i = opFlags.begin();
- i != opFlags.end(); ++i)
+ foreach (Strings::iterator, i, opFlags)
if (*i == "--outputs") query = qOutputs;
else if (*i == "--requisites" || *i == "-R") query = qRequisites;
else if (*i == "--references") query = qReferences;
@@ -286,6 +285,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
else if (*i == "--tree") query = qTree;
else if (*i == "--graph") query = qGraph;
else if (*i == "--resolve") query = qResolve;
+ else if (*i == "--roots") query = qRoots;
else if (*i == "--use-output" || *i == "-u") useOutput = true;
else if (*i == "--force-realise" || *i == "-f") forceRealise = true;
else if (*i == "--include-outputs") includeOutputs = true;
@@ -294,9 +294,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
switch (query) {
case qOutputs: {
- for (Strings::iterator i = opArgs.begin();
- i != opArgs.end(); ++i)
- {
+ foreach (Strings::iterator, i, opArgs) {
*i = followLinksToStorePath(*i);
if (forceRealise) realisePath(*i);
Derivation drv = derivationFromPath(*i);
@@ -310,9 +308,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
case qReferrers:
case qReferrersClosure: {
PathSet paths;
- for (Strings::iterator i = opArgs.begin();
- i != opArgs.end(); ++i)
- {
+ foreach (Strings::iterator, i, opArgs) {
Path path = maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise);
if (query == qRequisites)
storePathRequisites(path, includeOutputs, paths);
@@ -328,9 +324,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
}
case qDeriver:
- for (Strings::iterator i = opArgs.begin();
- i != opArgs.end(); ++i)
- {
+ foreach (Strings::iterator, i, opArgs) {
Path deriver = store->queryDeriver(followLinksToStorePath(*i));
cout << format("%1%\n") %
(deriver == "" ? "unknown-deriver" : deriver);
@@ -338,9 +332,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
break;
case qBinding:
- for (Strings::iterator i = opArgs.begin();
- i != opArgs.end(); ++i)
- {
+ foreach (Strings::iterator, i, opArgs) {
Path path = useDeriver(followLinksToStorePath(*i));
Derivation drv = derivationFromPath(path);
StringPairs::iterator j = drv.env.find(bindingName);
@@ -352,9 +344,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
break;
case qHash:
- for (Strings::iterator i = opArgs.begin();
- i != opArgs.end(); ++i)
- {
+ foreach (Strings::iterator, i, opArgs) {
Path path = maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise);
Hash hash = store->queryPathHash(path);
assert(hash.type == htSHA256);
@@ -364,28 +354,37 @@ static void opQuery(Strings opFlags, Strings opArgs)
case qTree: {
PathSet done;
- for (Strings::iterator i = opArgs.begin();
- i != opArgs.end(); ++i)
+ foreach (Strings::iterator, i, opArgs)
printTree(followLinksToStorePath(*i), "", "", done);
break;
}
case qGraph: {
PathSet roots;
- for (Strings::iterator i = opArgs.begin();
- i != opArgs.end(); ++i)
+ foreach (Strings::iterator, i, opArgs)
roots.insert(maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise));
printDotGraph(roots);
break;
}
case qResolve: {
- for (Strings::iterator i = opArgs.begin();
- i != opArgs.end(); ++i)
+ foreach (Strings::iterator, i, opArgs)
cout << format("%1%\n") % followLinksToStorePath(*i);
break;
}
+ case qRoots: {
+ PathSet referrers;
+ foreach (Strings::iterator, i, opArgs)
+ computeFSClosure(maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise),
+ referrers, true);
+ Roots roots = store->findRoots();
+ foreach (Roots::iterator, i, roots)
+ if (referrers.find(i->second) != referrers.end())
+ cout << format("%1%\n") % i->first;
+ break;
+ }
+
default:
abort();
}