about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRicardo M. Correia <rcorreia@wizy.org>2014-04-11T15·10+0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2014-04-15T13·34+0200
commit700c678c2eed5e05c3e68d722c41c2b37d0a2f45 (patch)
treeec015083ce9a97d3233a806c9540d335ad48198d
parentfb5d76b89e8b0084fb147d79af5481e09b889386 (diff)
nix-env: Minor change to '--delete-generations Nd' semantics
The option '--delete-generations Nd' deletes all generations older than N
days. However, most likely the user does not want to delete the
generation that was active N days ago.

For example, say that you have these 3 generations:

1: <30 days ago>
2: <15 days ago>
3: <1 hour ago>

If you do --delete-generations 7d (say, as part of a cron job), most
likely you still want to keep generation 2, i.e. the generation that was
active 7 days ago (and for most of the past 7 days, in fact).

This patch fixes this issue. Note that this also affects
'nix-collect-garbage --delete-older-than Nd'.

Thanks to @roconnor for noticing the issue!
-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 a97e3b7c6b..cf870740f4 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 3bfcb15dba..c440208034 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 8a80526347..3db84ff5c7 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;