about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2014-10-14T10·07+0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2014-10-14T10·08+0200
commit2c1711ae33c0824570dab4651c5aefd273e8eba6 (patch)
tree68ff7e352a8e8bfedd5d61d8bcfacc72f0626cee
parentc6849e2dee743d9a4aca30842244d956ddcd25c3 (diff)
nix-channel: Add --rollback flag
Fixes #368.
-rw-r--r--doc/manual/command-ref/nix-channel.xml55
-rwxr-xr-xscripts/nix-channel.in14
2 files changed, 68 insertions, 1 deletions
diff --git a/doc/manual/command-ref/nix-channel.xml b/doc/manual/command-ref/nix-channel.xml
index 63ecba8f3eb7..c4cc04ce24d8 100644
--- a/doc/manual/command-ref/nix-channel.xml
+++ b/doc/manual/command-ref/nix-channel.xml
@@ -24,6 +24,7 @@
       <arg choice='plain'><option>--remove</option> <replaceable>url</replaceable></arg>
       <arg choice='plain'><option>--list</option></arg>
       <arg choice='plain'><option>--update</option> <arg rep='repeat'><replaceable>names</replaceable></arg></arg>
+      <arg choice='plain'><option>--rollback</option> <arg choice='opt'><replaceable>generation</replaceable></arg></arg>
     </group>
   </cmdsynopsis>
 </refsynopsisdiv>
@@ -80,6 +81,14 @@ condition="manual">See also <xref linkend="sec-channels"
 
   </varlistentry>
 
+  <varlistentry><term><option>--rollback</option> [<replaceable>generation</replaceable>]</term>
+
+    <listitem><para>Reverts the previous call to <command>nix-channel
+    --update</command>. Optionally, you can specify a specific channel
+    generation number to restore.</para></listitem>
+
+  </varlistentry>
+
 </variablelist>
 
 </para>
@@ -104,10 +113,54 @@ respectively.</para>
 <para>To subscribe to the Nixpkgs channel and install the GNU Hello package:</para>
 
 <screen>
-$ nix-channel --add http://nixos.org/channels/nixpkgs-unstable
+$ nix-channel --add https://nixos.org/channels/nixpkgs-unstable
 $ nix-channel --update
 $ nix-env -iA nixpkgs.hello</screen>
 
+<para>You can revert channel updates using <option>--rollback</option>:</para>
+
+<screen>
+$ nix-instantiate --eval -E '(import &lt;nixpkgs> {}).lib.nixpkgsVersion'
+"14.04.527.0e935f1"
+
+$ nix-channel --rollback
+switching from generation 483 to 482
+
+$ nix-instantiate --eval -E '(import &lt;nixpkgs> {}).lib.nixpkgsVersion'
+"14.04.526.dbadfad"
+</screen>
+
+</refsection>
+
+<refsection><title>Files</title>
+
+<variablelist>
+
+  <varlistentry><term><filename>/nix/var/nix/profiles/<replaceable>username</replaceable>/channels</filename></term>
+
+    <listitem><para><command>nix-channel</command> uses a
+    <command>nix-env</command> profile to keep track of previous
+    versions of the subscribed channels. Every time you run
+    <command>nix-channel --update</command>, a new channel generation
+    (that is, a symlink to the channel Nix expressions in the Nix store)
+    is created. This enables <command>nix-channel --rollback</command>
+    to revert to previous versions.</para></listitem>
+
+  </varlistentry>
+
+  <varlistentry><term><filename>~/.nix-defexpr/channels</filename></term>
+
+    <listitem><para>This is a symlink to
+    <filename>/nix/var/nix/profiles/<replaceable>username</replaceable>/channels</filename>. It
+    ensures that <command>nix-env</command> can find your channels. In
+    a multi-user installation, you may also have
+    <filename>~/.nix-defexpr/channels_root</filename>, which links to
+    the channels of the root user.</para></listitem>
+
+  </varlistentry>
+
+</variablelist>
+
 </refsection>
 
 </refentry>
diff --git a/scripts/nix-channel.in b/scripts/nix-channel.in
index 8e07821c43c7..b8c93df18c32 100755
--- a/scripts/nix-channel.in
+++ b/scripts/nix-channel.in
@@ -199,6 +199,20 @@ while (scalar @ARGV) {
         last;
     }
 
+    elsif ($arg eq "--rollback") {
+        die "$0: ‘--rollback’ has at most one argument\n" if scalar @ARGV > 1;
+        my $generation = shift @ARGV;
+        my @args = ("$Nix::Config::binDir/nix-env", "--profile", $profile);
+        if (defined $generation) {
+            die "invalid channel generation number ‘$generation’" unless $generation =~ /^[0-9]+$/;
+            push @args, "--switch-generation", $generation;
+        } else {
+            push @args, "--rollback";
+        }
+        system(@args) == 0 or exit 1;
+        last;
+    }
+
     elsif ($arg eq "--help") {
         exec "man nix-channel" or die;
     }