--- old-ghc/darcs-all	2009-03-30 09:45:25.312500000 +0100
+++ new-ghc/darcs-all	2009-03-30 09:45:25.437500000 +0100
@@ -52,6 +52,10 @@
 
 my %tags;
 
+my %warnings;
+my %conflicts;
+my %missing;
+
 sub message {
     if ($verbose >= 2) {
         print "@_\n";
@@ -66,18 +70,42 @@
 
 sub darcs {
     message "== running darcs @_";
-    system ("darcs", @_) == 0
+
+    # run darcs, track std and err output
+    open(DARCS,"darcs @_ 2>&1 |")
+        or $ignore_failure
+        or die "can't start darcs: $?";
+
+    # keep per-package record of warnings, errors and conflicts
+    my $previous = "";
+    while (<DARCS>) {
+      if (/^Warning/ || /^darcs/ || /^realdarcs/ || /^Backing/) {
+        $warnings{$_[$#_]} .= $_;
+      } elsif ($previous =~ /^We have conflicts/) {
+        $conflicts{$_[$#_]} .= $_;
+      }
+      $previous = $_;
+      print $_;
+    }
+    close(DARCS)
         or $ignore_failure
-        or die "darcs failed: $?";
+        or die "darcs failed ($!): $?";
 }
 
 sub darcsall {
     my $localpath;
     my $path;
     my $tag;
+    my %modtime;
     my @repos;
 
+    # read and close packages before calling darcs, which might
+    # try to update that file
     open IN, "< packages" or die "Can't open packages file";
+
+    # keep track of who we are
+    $modtime{"darcs-all"} = (stat("darcs-all"))[9];
+    $modtime{"packages"}  = (stat("packages"))[9];
     @repos = <IN>;
     close IN;
 
@@ -89,18 +117,56 @@
 
             if (-d "$localpath/_darcs") {
                 darcs (@_, "--repodir", $localpath);
+
+                # if we have updated ourselves, all bets are off
+                if ($localpath eq ".") {
+                  my $darcs_all_mod = ((stat("darcs-all"))[9] != $modtime{"darcs-all"});
+                  my $packages_mod  = ((stat("packages"))[9] != $modtime{"packages"});
+                  if ($darcs_all_mod || $packages_mod) { 
+                      summary();
+                      die "'darcs-all' ".($darcs_all_mod?"(changed)":"").
+                      " or 'packages' ".($packages_mod?"(changed)":"")." updated;\n".
+                      "please re-run your darcs-all command"; 
+                    }
+                }
             }
             elsif ($tag eq "") {
                 message "== Required repo $localpath is missing! Skipping";
+                $missing{$localpath} = "(required repo!)";
             }
             else {
                 message "== $localpath repo not present; skipping";
+                $missing{$localpath} = "(optional '$tag' repo)";
             }
         }
         elsif (! /^(#.*)?$/) {
             die "Bad line: $_";
         }
     }
+    summary();
+}
+
+# summarize warnings and conflicts
+sub summary {
+    my $package;
+    if (scalar(%warnings)) {
+      print "\n-- there are Warnings\n";
+      foreach $package (keys%warnings) { 
+        print "-- Warnings for $package:\n$warnings{$package}\n";
+      }
+    }
+    if (scalar(%conflicts)) {
+      print "\n-- there are Conflicts\n"; 
+      foreach $package (keys%conflicts) { 
+        print "-- Conflicts in $package:\n$conflicts{$package}\n";
+      }
+    }
+    if (scalar(%missing)) {
+      print "\n-- there are missing packages:\n";
+      foreach $package (keys%missing) {
+        print "$package $missing{$package}\n";
+      }
+    }
 }
 
 sub darcsget {

