about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--doc/manual/nix-store.xml23
-rw-r--r--src/nix-store/help.txt15
-rw-r--r--src/nix-store/nix-store.cc47
3 files changed, 53 insertions, 32 deletions
diff --git a/doc/manual/nix-store.xml b/doc/manual/nix-store.xml
index 562a5439a6eb..566c75bf3e9f 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'
     <arg choice='plain'><option>--tree</option></arg>
     <arg choice='plain'><option>--binding</option> <replaceable>name</replaceable></arg>
     <arg choice='plain'><option>--hash</option></arg>
+    <arg choice='plain'><option>--roots</option></arg>
   </group>
   <arg><option>--use-output</option></arg>
   <arg><option>-u</option></arg>
@@ -586,12 +587,20 @@ query is applied to the target of the symlink.</para>
   <varlistentry><term><option>--hash</option></term>
   
     <listitem><para>Prints the SHA-256 hash of the contents of the
-    store path <replaceable>paths</replaceable>.  Since the hash is
+    store paths <replaceable>paths</replaceable>.  Since the hash is
     stored in the Nix database, this is a fast
     operation.</para></listitem>
 
   </varlistentry>
 
+  <varlistentry><term><option>--roots</option></term>
+  
+    <listitem><para>Prints the garbage collector roots that point,
+    directly or indirectly, at the store paths
+    <replaceable>paths</replaceable>.</para></listitem>
+
+  </varlistentry>
+
 </variablelist>
 
 </refsection>
@@ -669,6 +678,18 @@ $ gv graph.ps</screen>
 
 </para>
 
+<para>Show every garbage collector root that points to a store path
+that depends on <command>svn</command>:
+
+<screen>
+$ 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
+</screen>
+
+</para>
+
 </refsection>
 
 
diff --git a/src/nix-store/help.txt b/src/nix-store/help.txt
index c4981168bdcc..7576e3ef5d42 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 b951393092b9..e08908cd78ec 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();
     }