X-Git-Url: https://git.madduck.net/code/myrepos.git/blobdiff_plain/49414b4e3aa308c2691c2bed417469144d436637..1ff64653e8a4b53b1a132e1fed293de8d170d7ce:/mr?ds=sidebyside

diff --git a/mr b/mr
index 74d0129..5e0ac7f 100755
--- a/mr
+++ b/mr
@@ -232,7 +232,7 @@ 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.
 
-  skip = test $(whoami) != joey
+  skip = test `whoami` != joey
   skip = [ "$1" = update ] && ! hours_since "$1" 12
 
 =item order
@@ -296,7 +296,8 @@ use warnings;
 use strict;
 use Getopt::Long;
 use Cwd qw(getcwd abs_path);
-use POSIX "WNOHANG";
+
+# things that can happen when mr runs a command
 use constant {
 	OK => 0,
 	FAILED => 1,
@@ -304,252 +305,40 @@ use constant {
 	ABORT => 3,
 };
 
-$SIG{INT}=sub {
-	print STDERR "mr: interrupted\n";
-	exit 2;
-};
-
-$ENV{MR_CONFIG}="$ENV{HOME}/.mrconfig";
+# configurables
 my $config_overridden=0;
 my $verbose=0;
 my $stats=0;
 my $no_recurse=0;
+my $no_chdir=0;
 my $jobs=1;
+my $directory=getcwd();
+$ENV{MR_CONFIG}="$ENV{HOME}/.mrconfig";
+
+# globals :-(
 my %config;
 my %configfiles;
 my %knownactions;
 my %alias;
-my $directory=getcwd();
-
-Getopt::Long::Configure("no_permute");
-my $result=GetOptions(
-	"d|directory=s" => sub { $directory=abs_path($_[1]) },
-	"c|config=s" => sub { $ENV{MR_CONFIG}=$_[1]; $config_overridden=1 },
-	"v|verbose" => \$verbose,
-	"s|stats" => \$stats,
-	"n|no-recurse" => \$no_recurse,
-	"j|jobs=i" => \$jobs,
-);
-if (! $result || @ARGV < 1) {
-	die("Usage: mr [-d directory] action [params ...]\n".
-	    "(Use mr help for man page.)\n");
-
-}
-if (! defined $directory) {
-	die("mr: failed to determine working directory\n");
-}
-
-# Make sure MR_CONFIG is an absolute path, but don't use abs_path since
-# the config file might be a symlink to elsewhere, and the directory it's
-# in is significant.
-if ($ENV{MR_CONFIG} !~ /^\//) {
-	$ENV{MR_CONFIG}=getcwd()."/".$ENV{MR_CONFIG};
-}
-# Try to set MR_PATH to the path to the program.
-eval {
-	use FindBin qw($Bin $Script);
-	$ENV{MR_PATH}=$Bin."/".$Script;
-};
-
-loadconfig(\*DATA);
-loadconfig($ENV{MR_CONFIG});
-#use Data::Dumper;
-#print Dumper(\%config);
-
-# alias expansion and command stemming
-my $action=shift @ARGV;
-if (exists $alias{$action}) {
-	$action=$alias{$action};
-}
-if (! exists $knownactions{$action}) {
-	my @matches = grep { /^\Q$action\E/ }
-		keys %knownactions, keys %alias;
-	if (@matches == 1) {
-		$action=$matches[0];
-	}
-	elsif (@matches == 0) {
-		die "mr: unknown action \"$action\" (known actions: ".
-			join(", ", sort keys %knownactions).")\n";
-	}
-	else {
-		die "mr: ambiguous action \"$action\" (matches: ".
-			join(", ", @matches).")\n";
-	}
-}
-
-# commands that do not operate on all repos
-if ($action eq 'help') {
-	exec($config{''}{DEFAULT}{$action}) || die "exec: $!";
-}
-elsif ($action eq 'config') {
-	if (@ARGV < 2) {
-		die "mr config: not enough parameters\n";
-	}
-	my $section=shift;
-	if ($section=~/^\//) {
-		# try to convert to a path relative to the config file
-		my ($dir)=$ENV{MR_CONFIG}=~/^(.*\/)[^\/]+$/;
-		$dir=abs_path($dir);
-		$dir.="/" unless $dir=~/\/$/;
-		if ($section=~/^\Q$dir\E(.*)/) {
-			$section=$1;
-		}
-	}
-	my %changefields;
-	foreach (@ARGV) {
-		if (/^([^=]+)=(.*)$/) {
-			$changefields{$1}=$2;
-		}
-		else {
-			my $found=0;
-			foreach my $topdir (sort keys %config) {
-				if (exists $config{$topdir}{$section} &&
-				    exists $config{$topdir}{$section}{$_}) {
-					print $config{$topdir}{$section}{$_}."\n";
-					$found=1;
-					last if $section eq 'DEFAULT';
-				}
-			}
-			if (! $found) {
-				die "mr $action: $section $_ not set\n";
-			}
-		}
-	}
-	modifyconfig($ENV{MR_CONFIG}, $section, %changefields) if %changefields;
-	exit 0;
-}
-elsif ($action eq 'register') {
-	if (! $config_overridden) {
-		# Find the closest known mrconfig file to the current
-		# directory.
-		$directory.="/" unless $directory=~/\/$/;
-		foreach my $topdir (reverse sort keys %config) {
-			next unless length $topdir;
-			if ($directory=~/^\Q$topdir\E/) {
-				$ENV{MR_CONFIG}=$configfiles{$topdir};
-				last;
-			}
-		}
-	}
-	if (@ARGV) {
-		my $subdir=shift @ARGV;
-		if (! chdir($subdir)) {
-			print STDERR "mr $action: failed to chdir to $subdir: $!\n";
-		}
-	}
-
-	$ENV{MR_REPO}=getcwd();
-	my $command=findcommand("register", '', '', 'DEFAULT');
-	if (! defined $command) {
-		die "mr $action: unknown repository type\n";
-	}
-
-	$ENV{MR_REPO}=~s/.*\/(.*)/$1/;
-	$command="set -e; ".$config{''}{DEFAULT}{lib}."\n".
-		"my_action(){ $command\n }; my_action ".
-		join(" ", map { s/\//\/\//g; s/"/\"/g; '"'.$_.'"' } @ARGV);
-	print "mr $action: running >>$command<<\n" if $verbose;
-	exec($command) || die "exec: $!";
-}
-
-# an ordered list of repos
-my @list;
-foreach my $topdir (sort keys %config) {
-	foreach my $subdir (sort keys %{$config{$topdir}}) {
-		push @list, {
-			topdir => $topdir,
-			subdir => $subdir,
-			order => $config{$topdir}{$subdir}{order},
-		};
-	}
-}
-@list = sort {
-		$a->{order}  <=> $b->{order}
-		             ||
-		$a->{topdir} cmp $b->{topdir}
-		             ||
-		$a->{subdir} cmp $b->{subdir}
-	} @list;
-
-# work out what repos to act on
-my @repos;
-my $nochdir=0;
-foreach my $repo (@list) {
-	my $topdir=$repo->{topdir};
-	my $subdir=$repo->{subdir};
-
-	next if $subdir eq 'DEFAULT';
-	my $dir=($subdir =~/^\//) ? $subdir : $topdir.$subdir;
-	my $d=$directory;
-	$dir.="/" unless $dir=~/\/$/;
-	$d.="/" unless $d=~/\/$/;
-	next if $no_recurse && $d ne $dir;
-	next if $dir ne $d && $dir !~ /^\Q$d\E/;
-	push @repos, [$dir, $topdir, $subdir];
-}
-if (! @repos) {
-	# fallback to find a leaf repo
-	foreach my $repo (reverse @list) {
-		my $topdir=$repo->{topdir};
-		my $subdir=$repo->{subdir};
-		
-		next if $subdir eq 'DEFAULT';
-		my $dir=($subdir =~/^\//) ? $subdir : $topdir.$subdir;
-		my $d=$directory;
-		$dir.="/" unless $dir=~/\/$/;
-		$d.="/" unless $d=~/\/$/;
-		if ($d=~/^\Q$dir\E/) {
-			push @repos, [$dir, $topdir, $subdir];
-			last;
-		}
-	}
-	$nochdir=1;
-}
-
-# run the action on each repository and print stats
 my (@ok, @failed, @skipped);
-if ($jobs > 1) {
-	mrs(@repos);
-}
-else {
-	foreach my $repo (@repos) {
-		record($repo, action($action, @$repo));
-	}
-}
-if (! @ok && ! @failed && ! @skipped) {
-	die "mr $action: no repositories found to work on\n";
-}
-print "mr $action: finished (".join("; ",
-	showstat($#ok+1, "ok", "ok"),
-	showstat($#failed+1, "failed", "failed"),
-	showstat($#skipped+1, "skipped", "skipped"),
-).")\n";
-if ($stats) {
-	if (@skipped) {
-		print "mr $action: (skipped: ".join(" ", @skipped).")\n";
-	}
-	if (@failed) {
-		print STDERR "mr $action: (failed: ".join(" ", @failed).")\n";
-	}
-}
-if (@failed) {
-	exit 1;
-}
-elsif (! @ok && @skipped) {
-	exit 1;
-}
-exit 0;
 
+main();
+
+my %rcs;
 sub rcs_test { #{{{
 	my ($action, $dir, $topdir, $subdir) = @_;
 
+	if (exists $rcs{$dir}) {
+		return $rcs{$dir};
+	}
+
 	my $test="set -e\n";
 	foreach my $rcs_test (
 			sort {
 				length $a <=> length $b 
 				          ||
 				       $a cmp $b
-			} grep { /_test/ } keys %{$config{$topdir}{$subdir}}) {
+			} 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";
@@ -560,21 +349,30 @@ sub rcs_test { #{{{
 	print "mr $action: running rcs test >>$test<<\n" if $verbose;
 	my $rcs=`$test`;
 	chomp $rcs;
-	if (! length $rcs) {
+	if ($rcs=~/\n/s) {
+		$rcs=~s/\n/, /g;
+		print STDERR "mr $action: found multiple possible repository types ($rcs) for $topdir$subdir\n";
 		return undef;
 	}
+	if (! length $rcs) {
+		return $rcs{$dir}=undef;
+	}
 	else {
-		return $rcs;
+		return $rcs{$dir}=$rcs;
 	}
 } #}}}
 	
 sub findcommand { #{{{
-	my ($action, $dir, $topdir, $subdir) = @_;
+	my ($action, $dir, $topdir, $subdir, $is_checkout) = @_;
 	
 	if (exists $config{$topdir}{$subdir}{$action}) {
 		return $config{$topdir}{$subdir}{$action};
 	}
 
+	if ($is_checkout) {
+		return undef;
+	}
+
 	my $rcs=rcs_test(@_);
 
 	if (defined $rcs && 
@@ -592,19 +390,15 @@ sub action { #{{{
 	$ENV{MR_CONFIG}=$configfiles{$topdir};
 	my $lib=exists $config{$topdir}{$subdir}{lib} ?
 	               $config{$topdir}{$subdir}{lib}."\n" : "";
+	my $is_checkout=($action eq 'checkout');
 
-	if ($action eq 'checkout') {
+	if ($is_checkout) {
 		if (-d $dir) {
 			print "mr $action: $dir already exists, skipping checkout\n" if $verbose;
 			return SKIPPED;
 		}
 
 		$dir=~s/^(.*)\/[^\/]+\/?$/$1/;
-
-		if (! -d $dir) {
-			print "mr $action: creating parent directory $dir\n" if $verbose;
-			system("mkdir", "-p", $dir);
-		}
 	}
 	elsif ($action =~ /update/) {
 		if (! -d $dir) {
@@ -614,8 +408,8 @@ sub action { #{{{
 
 	$ENV{MR_REPO}=$dir;
 
-	my $skiptest=findcommand("skip", $dir, $topdir, $subdir);
-	my $command=findcommand($action, $dir, $topdir, $subdir);
+	my $skiptest=findcommand("skip", $dir, $topdir, $subdir, $is_checkout);
+	my $command=findcommand($action, $dir, $topdir, $subdir, $is_checkout);
 
 	if (defined $skiptest) {
 		my $test="set -e;".$lib.
@@ -637,8 +431,13 @@ sub action { #{{{
 			return SKIPPED;
 		}
 	}
-	
-	if (! $nochdir && ! chdir($dir)) {
+
+	if ($is_checkout && ! -d $dir) {
+		print "mr $action: creating parent directory $dir\n" if $verbose;
+		system("mkdir", "-p", $dir);
+	}
+
+	if (! $no_chdir && ! chdir($dir)) {
 		print STDERR "mr $action: failed to chdir to $dir: $!\n";
 		return FAILED;
 	}
@@ -649,12 +448,12 @@ sub action { #{{{
 			return FAILED;
 		}
 		else {
-			print STDERR "mr $action: no defined $action command for $rcs repository $topdir$subdir, skipping\n";
+			print STDERR "mr $action: no defined action for $rcs repository $topdir$subdir, skipping\n";
 			return SKIPPED;
 		}
 	}
 	else {
-		if (! $nochdir) {
+		if (! $no_chdir) {
 			print "mr $action: $topdir$subdir\n";
 		}
 		else {
@@ -698,6 +497,9 @@ sub action { #{{{
 
 # run actions on multiple repos, in parallel
 sub mrs { #{{{
+	my $action=shift;
+	my @repos=@_;
+
 	$| = 1;
 	my @active;
 	my @fhs;
@@ -786,6 +588,26 @@ sub record { #{{{
 	}
 } #}}}
 
+sub showstats { #{{{
+	my $action=shift;
+	if (! @ok && ! @failed && ! @skipped) {
+		die "mr $action: no repositories found to work on\n";
+	}
+	print "mr $action: finished (".join("; ",
+		showstat($#ok+1, "ok", "ok"),
+		showstat($#failed+1, "failed", "failed"),
+		showstat($#skipped+1, "skipped", "skipped"),
+	).")\n";
+	if ($stats) {
+		if (@skipped) {
+			print "mr $action: (skipped: ".join(" ", @skipped).")\n";
+		}
+		if (@failed) {
+			print STDERR "mr $action: (failed: ".join(" ", @failed).")\n";
+		}
+	}
+} #}}}
+
 sub showstat { #{{{
 	my $count=shift;
 	my $singular=shift;
@@ -796,6 +618,64 @@ sub showstat { #{{{
 	return;
 } #}}}
 
+# an ordered list of repos
+sub repolist { #{{{
+	my @list;
+	foreach my $topdir (sort keys %config) {
+		foreach my $subdir (sort keys %{$config{$topdir}}) {
+			push @list, {
+				topdir => $topdir,
+				subdir => $subdir,
+				order => $config{$topdir}{$subdir}{order},
+			};
+		}
+	}
+	return sort {
+		$a->{order}  <=> $b->{order}
+		             ||
+		$a->{topdir} cmp $b->{topdir}
+		             ||
+		$a->{subdir} cmp $b->{subdir}
+	} @list;
+} #}}}
+
+# figure out which repos to act on
+sub selectrepos { #{{{
+	my @repos;
+	foreach my $repo (repolist()) {
+		my $topdir=$repo->{topdir};
+		my $subdir=$repo->{subdir};
+
+		next if $subdir eq 'DEFAULT';
+		my $dir=($subdir =~/^\//) ? $subdir : $topdir.$subdir;
+		my $d=$directory;
+		$dir.="/" unless $dir=~/\/$/;
+		$d.="/" unless $d=~/\/$/;
+		next if $no_recurse && $d ne $dir;
+		next if $dir ne $d && $dir !~ /^\Q$d\E/;
+		push @repos, [$dir, $topdir, $subdir];
+	}
+	if (! @repos) {
+		# fallback to find a leaf repo
+		foreach my $repo (reverse repolist()) {
+			my $topdir=$repo->{topdir};
+			my $subdir=$repo->{subdir};
+			
+			next if $subdir eq 'DEFAULT';
+			my $dir=($subdir =~/^\//) ? $subdir : $topdir.$subdir;
+			my $d=$directory;
+			$dir.="/" unless $dir=~/\/$/;
+			$d.="/" unless $d=~/\/$/;
+			if ($d=~/^\Q$dir\E/) {
+				push @repos, [$dir, $topdir, $subdir];
+				last;
+			}
+		}
+		$no_chdir=1;
+	}
+	return @repos;
+} #}}}
+
 my %loaded;
 sub loadconfig { #{{{
 	my $f=shift;
@@ -905,11 +785,11 @@ sub loadconfig { #{{{
 					my $ret=system($value);
 					if ($ret != 0) {
 						if (($? & 127) == 2) {
-							print STDERR "mr $action: chain test interrupted\n";
+							print STDERR "mr: chain test interrupted\n";
 							exit 2;
 						}
 						elsif ($? & 127) {
-							print STDERR "mr $action: chain test received signal ".($? & 127)."\n";
+							print STDERR "mr: chain test received signal ".($? & 127)."\n";
 						}
 					}
 					else {
@@ -1025,6 +905,198 @@ sub modifyconfig { #{{{
 	close $out;	
 } #}}}
 
+sub dispatch { #{{{
+	my $action=shift;
+
+	# actions that do not operate on all repos
+	if ($action eq 'help') {
+		help(@ARGV);
+	}
+	elsif ($action eq 'config') {
+		config(@ARGV);
+	}
+	elsif ($action eq 'register') {
+		register(@ARGV);
+	}
+
+	if ($jobs > 1) {
+		mrs($action, selectrepos());
+	}
+	else {
+		foreach my $repo (selectrepos()) {
+			record($repo, action($action, @$repo));
+		}
+	}
+} #}}}
+
+sub help { #{{{
+	exec($config{''}{DEFAULT}{help}) || die "exec: $!";
+} #}}}
+	
+sub config { #{{{
+	if (@_ < 2) {
+		die "mr config: not enough parameters\n";
+	}
+	my $section=shift;
+	if ($section=~/^\//) {
+		# try to convert to a path relative to the config file
+		my ($dir)=$ENV{MR_CONFIG}=~/^(.*\/)[^\/]+$/;
+		$dir=abs_path($dir);
+		$dir.="/" unless $dir=~/\/$/;
+		if ($section=~/^\Q$dir\E(.*)/) {
+			$section=$1;
+		}
+	}
+	my %changefields;
+	foreach (@_) {
+		if (/^([^=]+)=(.*)$/) {
+			$changefields{$1}=$2;
+		}
+		else {
+			my $found=0;
+			foreach my $topdir (sort keys %config) {
+				if (exists $config{$topdir}{$section} &&
+				    exists $config{$topdir}{$section}{$_}) {
+					print $config{$topdir}{$section}{$_}."\n";
+					$found=1;
+					last if $section eq 'DEFAULT';
+				}
+			}
+			if (! $found) {
+				die "mr config: $section $_ not set\n";
+			}
+		}
+	}
+	modifyconfig($ENV{MR_CONFIG}, $section, %changefields) if %changefields;
+	exit 0;
+} #}}}
+
+sub register { #{{{
+	if (! $config_overridden) {
+		# Find the closest known mrconfig file to the current
+		# directory.
+		$directory.="/" unless $directory=~/\/$/;
+		my $foundconfig=0;
+		foreach my $topdir (reverse sort keys %config) {
+			next unless length $topdir;
+			if ($directory=~/^\Q$topdir\E/) {
+				$ENV{MR_CONFIG}=$configfiles{$topdir};
+				$directory=$topdir;
+				$foundconfig=1;
+				last;
+			}
+		}
+		if (! $foundconfig) {
+			$directory=""; # no config file, use builtin
+		}
+	}
+	if (@ARGV) {
+		my $subdir=shift @ARGV;
+		if (! chdir($subdir)) {
+			print STDERR "mr register: failed to chdir to $subdir: $!\n";
+		}
+	}
+
+	$ENV{MR_REPO}=getcwd();
+	my $command=findcommand("register", $ENV{MR_REPO}, $directory, 'DEFAULT', 0);
+	if (! defined $command) {
+		die "mr register: unknown repository type\n";
+	}
+
+	$ENV{MR_REPO}=~s/.*\/(.*)/$1/;
+	$command="set -e; ".$config{$directory}{DEFAULT}{lib}."\n".
+		"my_action(){ $command\n }; my_action ".
+		join(" ", map { s/\//\/\//g; s/"/\"/g; '"'.$_.'"' } @ARGV);
+	print "mr register: running >>$command<<\n" if $verbose;
+	exec($command) || die "exec: $!";
+} #}}}
+
+# alias expansion and command stemming
+sub expandaction { #{{{
+	my $action=shift;
+	if (exists $alias{$action}) {
+		$action=$alias{$action};
+	}
+	if (! exists $knownactions{$action}) {
+		my @matches = grep { /^\Q$action\E/ }
+			keys %knownactions, keys %alias;
+		if (@matches == 1) {
+			$action=$matches[0];
+		}
+		elsif (@matches == 0) {
+			die "mr: unknown action \"$action\" (known actions: ".
+				join(", ", sort keys %knownactions).")\n";
+		}
+		else {
+			die "mr: ambiguous action \"$action\" (matches: ".
+				join(", ", @matches).")\n";
+		}
+	}
+	return $action;
+} #}}}
+
+sub getopts { #{{{
+	Getopt::Long::Configure("bundling", "no_permute");
+	my $result=GetOptions(
+		"d|directory=s" => sub { $directory=abs_path($_[1]) },
+		"c|config=s" => sub { $ENV{MR_CONFIG}=$_[1]; $config_overridden=1 },
+		"v|verbose" => \$verbose,
+		"s|stats" => \$stats,
+		"n|no-recurse" => \$no_recurse,
+		"j|jobs=i" => \$jobs,
+	);
+	if (! $result || @ARGV < 1) {
+		die("Usage: mr [-d directory] action [params ...]\n".
+		    "(Use mr help for man page.)\n");
+	}
+} #}}}
+
+sub init { #{{{
+	$SIG{INT}=sub {
+		print STDERR "mr: interrupted\n";
+		exit 2;
+	};
+	
+	# This can happen if it's run in a directory that was removed
+	# or other strangeness.
+	if (! defined $directory) {
+		die("mr: failed to determine working directory\n");
+	}
+	# Make sure MR_CONFIG is an absolute path, but don't use abs_path since
+	# the config file might be a symlink to elsewhere, and the directory it's
+	# in is significant.
+	if ($ENV{MR_CONFIG} !~ /^\//) {
+		$ENV{MR_CONFIG}=getcwd()."/".$ENV{MR_CONFIG};
+	}
+	# Try to set MR_PATH to the path to the program.
+	eval {
+		use FindBin qw($Bin $Script);
+		$ENV{MR_PATH}=$Bin."/".$Script;
+	};
+} #}}}
+
+sub main { #{{{
+	getopts();
+	init();
+	loadconfig(\*DATA);
+	loadconfig($ENV{MR_CONFIG});
+	#use Data::Dumper; print Dumper(\%config);
+
+	my $action=expandaction(shift @ARGV);
+	dispatch($action);
+	showstats($action);
+
+	if (@failed) {
+		exit 1;
+	}
+	elsif (! @ok && @skipped) {
+		exit 1;
+	}
+	else {
+		exit 0;
+	}
+} #}}}
+
 # Finally, some useful actions that mr knows about by default.
 # These can be overridden in ~/.mrconfig.
 #DATA{{{
@@ -1060,7 +1132,7 @@ lib =
 		if [ -z "$flagfile" ]; then
 			error "cannot determine flag filename"
 		fi
-		delta=$(perl -wle 'print -f shift() ? int((-M _) * 24) : 9999' "$flagfile")
+		delta=`perl -wle 'print -f shift() ? int((-M _) * 24) : 9999' "$flagfile"`
 		if [ "$delta" -lt "$2" ]; then
 			exit 0
 		else
@@ -1078,7 +1150,7 @@ darcs_test = test -d "$MR_REPO"/_darcs
 git_bare_test =
 	test -d "$MR_REPO"/refs/heads && test -d "$MR_REPO"/refs/tags &&
 	test -d "$MR_REPO"/objects && test -f "$MR_REPO"/config &&
-	test "$(GIT_CONFIG="$MR_REPO"/config git-config --get core.bare)" = true
+	test "`GIT_CONFIG="$MR_REPO"/config git config --get core.bare`" = true
 
 svn_update = svn update "$@"
 git_update = if [ "$@" ]; then git pull "$@"; else git pull -t origin master; fi
@@ -1117,49 +1189,49 @@ darcs_log = darcs changes "$@"
 git_bare_log = git log "$@"
 
 svn_register =
-	url=$(LANG=C svn info . | grep -i ^URL: | cut -d ' ' -f 2)
+	url=`LANG=C svn info . | grep -i '^URL:' | cut -d ' ' -f 2`
 	if [ -z "$url" ]; then
 		error "cannot determine svn url"
 	fi
 	echo "Registering svn url: $url in $MR_CONFIG"
-	mr -c "$MR_CONFIG" config "`pwd`" checkout="svn co $url $MR_REPO"
+	mr -c "$MR_CONFIG" config "`pwd`" checkout="svn co '$url' '$MR_REPO'"
 git_register = 
-	url="$(LANG=C git-config --get remote.origin.url)" || true
+	url="`LANG=C git config --get remote.origin.url`" || true
 	if [ -z "$url" ]; then
 		error "cannot determine git url"
 	fi
 	echo "Registering git url: $url in $MR_CONFIG"
-	mr -c "$MR_CONFIG" config "`pwd`" checkout="git clone $url $MR_REPO"
+	mr -c "$MR_CONFIG" config "`pwd`" checkout="git clone '$url' '$MR_REPO'"
 bzr_register =
-	url=$(cat .bzr/branch/parent)
+	url=`cat .bzr/branch/parent`
 	if [ -z "$url" ]; then
 		error "cannot determine bzr url"
 	fi
 	echo "Registering bzr url: $url in $MR_CONFIG"
-	mr -c "$MR_CONFIG" config "`pwd`" checkout="bzr clone $url $MR_REPO"
+	mr -c "$MR_CONFIG" config "`pwd`" checkout="bzr clone '$url' '$MR_REPO'"
 cvs_register =
-	repo=$(cat CVS/Repository)
-	root=$(cat CVS/Root)
+	repo=`cat CVS/Repository`
+	root=`cat CVS/Root`
 	if [ -z "$root" ]; then
 		error "cannot determine cvs root"
 		fi
 	echo "Registering cvs repository $repo at root $root"
-	mr -c "$MR_CONFIG" config "`pwd`" checkout="cvs -d '$root' co -d $MR_REPO $repo"
+	mr -c "$MR_CONFIG" config "`pwd`" checkout="cvs -d '$root' co -d '$MR_REPO' '$repo'"
 hg_register = 
-	url=$(hg showconfig paths.default)
+	url=`hg showconfig paths.default`
 	echo "Registering mercurial repo url: $url in $MR_CONFIG"
-	mr -c "$MR_CONFIG" config "`pwd`" checkout="hg clone $url $MR_REPO"
+	mr -c "$MR_CONFIG" config "`pwd`" checkout="hg clone '$url' '$MR_REPO'"
 darcs_register = 
-	url=$(cat _darcs/prefs/defaultrepo)
+	url=`cat _darcs/prefs/defaultrepo`
 	echo "Registering darcs repository $url in $MR_CONFIG"
-	mr -c "$MR_CONFIG" config "`pwd`" checkout="darcs get $url $MR_REPO"
+	mr -c "$MR_CONFIG" config "`pwd`" checkout="darcs get '$url'p '$MR_REPO'"
 git_bare_register = 
-	url="$(LANG=C GIT_CONFIG=config git-config --get remote.origin.url)" || true
+	url="`LANG=C GIT_CONFIG=config git config --get remote.origin.url`" || true
 	if [ -z "$url" ]; then
 		error "cannot determine git url"
 	fi
 	echo "Registering git url: $url in $MR_CONFIG"
-	mr -c "$MR_CONFIG" config "`pwd`" checkout="git clone --bare $url $MR_REPO"
+	mr -c "$MR_CONFIG" config "`pwd`" checkout="git clone --bare '$url' '$MR_REPO'"
 
 help =
 	if [ ! -e "$MR_PATH" ]; then