X-Git-Url: https://git.madduck.net/code/myrepos.git/blobdiff_plain/f7ed26bbe30b1c38e2c9767bff9c791631713fe7..f9f7242bc46863624b9096d0bcda50bbc098aa49:/mr?ds=sidebyside

diff --git a/mr b/mr
index 61e2102..3996b60 100755
--- a/mr
+++ b/mr
@@ -41,7 +41,7 @@ B<mr> [options] remember action [params ...]
 B<mr> is a Multiple Repository management tool. It can checkout, update, or
 perform other actions on a set of repositories as if they were one combined
 repository. It supports any combination of subversion, git, cvs, mercurial,
-bzr, darcs and fossil repositories, and support for other revision
+bzr, darcs and fossil repositories, and support for other version
 control systems can easily be added.
 
 B<mr> cds into and operates on all registered repositories at or below your
@@ -55,7 +55,7 @@ in turn chain load .mrconfig files from repositories. It also automatically
 looks for a .mrconfig file in the current directory, or in one of its
 parent directories.
 
-These predefined commands should be fairly familiar to users of any revision
+These predefined commands should be fairly familiar to users of any version
 control system:
 
 =over 4
@@ -87,14 +87,14 @@ The optional -m parameter allows specifying a commit message.
 =item record
 
 Records changes to the local repository, but does not push them to the
-remote repository. Only supported for distributed revision control systems.
+remote repository. Only supported for distributed version control systems.
 
 The optional -m parameter allows specifying a commit message.
 
 =item push
 
 Pushes committed local changes to the remote repository. A no-op for
-centralized revision control systems.
+centralized version control systems.
 
 =item diff
 
@@ -189,8 +189,8 @@ Actions can be abbreviated to any unambiguous substring, so
 update"
 
 Additional parameters can be passed to most commands, and are passed on
-unchanged to the underlying revision control system. This is mostly useful
-if the repositories mr will act on all use the same revision control
+unchanged to the underlying version control system. This is mostly useful
+if the repositories mr will act on all use the same version control
 system.
 
 =head1 OPTIONS
@@ -339,6 +339,9 @@ The "MR_CONFIG" environment variable is set to the .mrconfig file
 that defines the repo being acted on, or, if the repo is not yet in a config
 file, the .mrconfig file that should be modified to register the repo.
 
+The "MR_ACTION" environment variable is set to the command being run
+(update, checkout, etc).
+
 A few parameters have special meanings:
 
 =over 4
@@ -354,8 +357,21 @@ mr is run by joey. The second uses the hours_since function
 (included in mr's built-in library) to skip updating the repo unless it's
 been at least 12 hours since the last update.
 
+  [mystuff]
+  checkout = ...
   skip = test `whoami` != joey
+
+  [linux]
+  checkout = ...
   skip = [ "$1" = update ] && ! hours_since "$1" 12
+ 
+Another way to use skip is for a lazy checkout. This makes mr skip
+operating on a repo unless it already exists. To enable the 
+repo, you have to explicitly check it out (using "mr -d foo checkout").
+
+  [foo]
+  checkout = ...
+  skip = lazy
 
 =item order
 
@@ -381,6 +397,14 @@ part of the including file.
 Unlike all other parameters, this parameter does not need to be placed
 within a section.
 
+B<mr> ships several libraries that can be included to add support for
+additional version control type things (unison, git-svn, vcsh, git-fake-bare,
+git-subtree). To include them all, you could use:
+
+  include = cat /usr/share/mr/*
+
+See the individual files for details.
+
 =item deleted
 
 If the "deleted" parameter is set and its command returns true, then
@@ -413,15 +437,15 @@ run before committing; "post_update" is run after updating.
 
 When looking for a command to run for a given action, mr first looks for
 a parameter with the same name as the action. If that is not found, it
-looks for a parameter named "rcs_action" (substituting in the name of the
-revision control system and the action). The name of the revision control
-system is itself determined by running each defined "rcs_test" action,
+looks for a parameter named "VCS_action" (substituting in the name of the
+version control system and the action). The name of the version control
+system is itself determined by running each defined "VCS_test" action,
 until one succeeds.
 
 Internally, mr has settings for "git_update", "svn_update", etc. To change
-the action that is performed for a given revision control system, you can
-override these rcs specific actions. To add a new revision control system,
-you can just add rcs specific actions for it.
+the action that is performed for a given version control system, you can
+override these VCS specific actions. To add a new version control system,
+you can just add VCS specific actions for it.
 
 =head1 UNTRUSTED MRCONFIG FILES
 
@@ -503,41 +527,41 @@ my (@ok, @failed, @skipped);
 
 main();
 
-my %rcs;
-sub rcs_test {
+my %vcs;
+sub vcs_test {
 	my ($action, $dir, $topdir, $subdir) = @_;
 
-	if (exists $rcs{$dir}) {
-		return $rcs{$dir};
+	if (exists $vcs{$dir}) {
+		return $vcs{$dir};
 	}
 
 	my $test="set -e\n";
-	foreach my $rcs_test (
+	foreach my $vcs_test (
 			sort {
 				length $a <=> length $b 
 				          ||
 				       $a cmp $b
 			} grep { /_test$/ } keys %{$config{$topdir}{$subdir}}) {
-		my ($rcs)=$rcs_test=~/(.*)_test/;
-		$test="my_$rcs_test() {\n$config{$topdir}{$subdir}{$rcs_test}\n}\n".$test;
-		$test.="if my_$rcs_test; then echo $rcs; fi\n";
+		my ($vcs)=$vcs_test=~/(.*)_test/;
+		$test="my_$vcs_test() {\n$config{$topdir}{$subdir}{$vcs_test}\n}\n".$test;
+		$test.="if my_$vcs_test; then echo $vcs; fi\n";
 	}
 	$test=$config{$topdir}{$subdir}{lib}."\n".$test
 		if exists $config{$topdir}{$subdir}{lib};
 	
-	print "mr $action: running rcs test >>$test<<\n" if $verbose;
-	my $rcs=`$test`;
-	chomp $rcs;
-	if ($rcs=~/\n/s) {
-		$rcs=~s/\n/, /g;
-		print STDERR "mr $action: found multiple possible repository types ($rcs) for ".fulldir($topdir, $subdir)."\n";
+	print "mr $action: running vcs test >>$test<<\n" if $verbose;
+	my $vcs=`$test`;
+	chomp $vcs;
+	if ($vcs=~/\n/s) {
+		$vcs=~s/\n/, /g;
+		print STDERR "mr $action: found multiple possible repository types ($vcs) for ".fulldir($topdir, $subdir)."\n";
 		return undef;
 	}
-	if (! length $rcs) {
-		return $rcs{$dir}=undef;
+	if (! length $vcs) {
+		return $vcs{$dir}=undef;
 	}
 	else {
-		return $rcs{$dir}=$rcs;
+		return $vcs{$dir}=$vcs;
 	}
 }
 	
@@ -552,11 +576,11 @@ sub findcommand {
 		return undef;
 	}
 
-	my $rcs=rcs_test(@_);
+	my $vcs=vcs_test(@_);
 
-	if (defined $rcs && 
-	    exists $config{$topdir}{$subdir}{$rcs."_".$action}) {
-		return $config{$topdir}{$subdir}{$rcs."_".$action};
+	if (defined $vcs && 
+	    exists $config{$topdir}{$subdir}{$vcs."_".$action}) {
+		return $config{$topdir}{$subdir}{$vcs."_".$action};
 	}
 	else {
 		return undef;
@@ -579,6 +603,7 @@ sub action {
 	my $is_update=($action =~ /update/);
 
 	$ENV{MR_REPO}=$dir;
+	$ENV{MR_ACTION}=$action;
 	
 	foreach my $testname ("skip", "deleted") {
 		my $testcommand=findcommand($testname, $dir, $topdir, $subdir, $is_checkout);
@@ -639,13 +664,13 @@ sub action {
 		return FAILED;
 	}
 	elsif (! defined $command) {
-		my $rcs=rcs_test(@_);
-		if (! defined $rcs) {
+		my $vcs=vcs_test(@_);
+		if (! defined $vcs) {
 			print STDERR "mr $action: unknown repository type and no defined $action command for $fulldir\n";
 			return FAILED;
 		}
 		else {
-			print STDERR "mr $action: no defined action for $rcs repository $fulldir, skipping\n";
+			print STDERR "mr $action: no defined action for $vcs repository $fulldir, skipping\n";
 			return SKIPPED;
 		}
 	}
@@ -755,6 +780,9 @@ sub hook {
 			print STDERR "mr $hook: received signal ".($? & 127)."\n";
 			return ABORT;
 		}
+		else {
+			return FAILED;
+		}
 	}
 
 	return OK;
@@ -1235,21 +1263,26 @@ sub loadconfig {
 					$knownactions{$parameter}=1;
 				}
 				if ($parameter eq 'chain' &&
-				    length $dir && $section ne "DEFAULT" &&
-				    -e $dir.$section."/.mrconfig") {
-					my $ret=system($value);
-					if ($ret != 0) {
-						if (($? & 127) == 2) {
-							print STDERR "mr: chain test interrupted\n";
-							exit 2;
+				    length $dir && $section ne "DEFAULT") {
+					my $chaindir="$section";
+					if ($chaindir !~ m!/!) {
+						$chaindir=$dir.$chaindir;
+					}
+					if (-e "$chaindir/.mrconfig") {
+						my $ret=system($value);
+						if ($ret != 0) {
+							if (($? & 127) == 2) {
+								print STDERR "mr: chain test interrupted\n";
+								exit 2;
+							}
+							elsif ($? & 127) {
+								print STDERR "mr: chain test received signal ".($? & 127)."\n";
+							}
 						}
-						elsif ($? & 127) {
-							print STDERR "mr: chain test received signal ".($? & 127)."\n";
+						else {
+							push @toload, ["$chaindir/.mrconfig", $chaindir];
 						}
 					}
-					else {
-						push @toload, $dir.$section."/.mrconfig";
-					}
 			        }
 			}
 		}
@@ -1258,8 +1291,8 @@ sub loadconfig {
 		}
 	}
 
-	foreach (@toload) {
-		loadconfig($_);
+	foreach my $c (@toload) {
+		loadconfig(@$c);
 	}
 }
 
@@ -1695,6 +1728,13 @@ lib =
 	is_bzr_checkout() {
 		LANG=C bzr info | egrep -q '^Checkout'
 	}
+	lazy() {
+		if [ "$MR_ACTION" = checkout ] || [ -d "$MR_REPO" ]; then
+			return 1
+		else
+			return 0
+		fi
+	}
 
 svn_test = test -d "$MR_REPO"/.svn
 git_test = test -d "$MR_REPO"/.git