about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--doc/manual/nix-collect-garbage.xml5
-rw-r--r--doc/manual/nix-env.xml3
-rw-r--r--src/nix-env/nix-env.cc14
3 files changed, 15 insertions, 7 deletions
diff --git a/doc/manual/nix-collect-garbage.xml b/doc/manual/nix-collect-garbage.xml
index a97e3b7c6ba5..cf870740f4ab 100644
--- a/doc/manual/nix-collect-garbage.xml
+++ b/doc/manual/nix-collect-garbage.xml
@@ -45,8 +45,9 @@ which deletes all old generations of all profiles in
 impossible); and
 <option>--delete-older-than</option> <replaceable>period</replaceable>,
 where period is a value such as <literal>30d</literal>, which deletes
-all non-current generations that are older than the specified number of
-days in all profiles in <filename>/nix/var/nix/profiles</filename>.
+all generations older than the specified number of days in all profiles
+in <filename>/nix/var/nix/profiles</filename> (except for the generations
+that were active at that point in time).
 </para>
 
 </refsection>
diff --git a/doc/manual/nix-env.xml b/doc/manual/nix-env.xml
index 3bfcb15dbac2..c44020803451 100644
--- a/doc/manual/nix-env.xml
+++ b/doc/manual/nix-env.xml
@@ -1170,7 +1170,8 @@ $ nix-env --list-generations
 profile.  The generations can be a list of generation numbers, the
 special value <literal>old</literal> to delete all non-current
 generations, or a value such as <literal>30d</literal> to delete all
-non-current generations older than the specified number of days.
+generations older than the specified number of days (except for the
+generation that was active at that point in time).
 Periodically deleting old generations is important to make garbage
 collection effective.</para>
 
diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc
index 8a805263477a..3db84ff5c7b5 100644
--- a/src/nix-env/nix-env.cc
+++ b/src/nix-env/nix-env.cc
@@ -1315,11 +1315,17 @@ static void opDeleteGenerations(Globals & globals,
 
             oldTime = curTime - days * 24 * 3600;
 
-            for (Generations::iterator j = gens.begin(); j != gens.end(); ++j) {
-                if (j->number == curGen) continue;
-
-                if (j->creationTime < oldTime)
+            bool canDelete = false;
+            for (Generations::reverse_iterator j = gens.rbegin(); j != gens.rend(); ++j) {
+                if (canDelete) {
+                    assert(j->creationTime < oldTime);
                     deleteGeneration2(globals, j->number);
+                } else if (j->creationTime < oldTime) {
+                    /* We may now start deleting generations, but we don't delete
+                       this generation yet, because this generation was still the
+                       one that was active at the requested point in time. */
+                    canDelete = true;
+                }
             }
         } else {
             int n;