summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--doc/guix.texi5
-rw-r--r--guix-package.in22
-rw-r--r--tests/guix-package.sh23
3 files changed, 39 insertions, 11 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index e1ca095daa..1385cd4532 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -509,6 +509,11 @@ the last transaction.
 When combined with options such as @code{--install}, roll back occurs
 before any other actions.
 
+When rolling back from the first generation that actually contains
+installed packages, the profile is made to point to the @dfn{empty
+profile}, also known as @dfn{profile zero}---i.e., it contains no files
+apart from its own meta-data.
+
 @item --profile=@var{profile}
 @itemx -p @var{profile}
 Use @var{profile} instead of the user's default profile.
diff --git a/guix-package.in b/guix-package.in
index 37a1df0c11..caddae1392 100644
--- a/guix-package.in
+++ b/guix-package.in
@@ -220,14 +220,26 @@ all of PACKAGES, a list of name/version/output/path tuples."
         (symlink previous-profile pivot)
         (rename-file pivot profile)))
 
-    (cond ((zero? number)
+    (cond ((not (file-exists? profile))           ; invalid profile
            (format (current-error-port)
-                   (_ "error: `~a' is not a valid profile~%")
+                   (_ "error: profile `~a' does not exist~%")
                    profile))
-          ((or (zero? previous-number)
+          ((zero? number)                         ; empty profile
+           (format (current-error-port)
+                   (_ "nothing to do: already at the empty profile~%")))
+          ((or (zero? previous-number)            ; going to emptiness
                (not (file-exists? previous-profile)))
-           (leave (_ "error: no previous profile; not rolling back~%")))
-          (else (switch-link)))))
+           (let*-values (((drv-path drv)
+                          (profile-derivation (%store) '()))
+                         ((prof)
+                          (derivation-output-path
+                           (assoc-ref (derivation-outputs drv) "out"))))
+             (when (not (build-derivations (%store) (list drv-path)))
+               (leave (_ "failed to build the empty profile~%")))
+
+             (symlink prof previous-profile)
+             (switch-link)))
+          (else (switch-link)))))                 ; anything else
 
 
 ;;;
diff --git a/tests/guix-package.sh b/tests/guix-package.sh
index 02ece68045..87b95236ff 100644
--- a/tests/guix-package.sh
+++ b/tests/guix-package.sh
@@ -81,9 +81,14 @@ then
     test "`readlink_base "$profile"`" = "$profile-1-link"
     test -x "$profile/bin/guile" && ! test -x "$profile/bin/make"
 
-    # Failed attempt to roll back because there's no previous generation.
-    if guix-package --roll-back -p "$profile";
-    then false; else true; fi
+    # Move to the empty profile.
+    for i in `seq 1 3`
+    do
+	guix-package --bootstrap --roll-back -p "$profile"
+	! test -f "$profile/bin"
+	! test -f "$profile/lib"
+	test "`readlink_base "$profile"`" = "$profile-0-link"
+    done
 
     # Reinstall after roll-back to generation 1.
     guix-package --bootstrap -p "$profile" -i "$boot_make"
@@ -136,9 +141,15 @@ then
     test "`cd $HOME/.guix-profile ; pwd`" = "$first_environment"
 fi
 
-# Failed attempt to roll back.
-if guix-package --bootstrap --roll-back;
-then false; else true; fi
+# Move to the empty profile.
+default_profile="`readlink "$HOME/.guix-profile"`"
+for i in `seq 1 3`
+do
+    guix-package --bootstrap --roll-back
+    ! test -f "$HOME/.guix-profile/bin"
+    ! test -f "$HOME/.guix-profile/lib"
+    test "`readlink "$default_profile"`" = "$default_profile-0-link"
+done
 
 # Extraneous argument.
 ! guix-package install foo-bar