X-Git-Url: https://git.madduck.net/code/myrepos.git/blobdiff_plain/c3ee87e2ac7bce77e805815bcfc31f7010a86086..6007e5d1f073c08daa25bd3057eaf3d3ac307071:/mr?ds=sidebyside

diff --git a/mr b/mr
index 9a33d40..494e89b 100755
--- a/mr
+++ b/mr
@@ -30,9 +30,9 @@ B<mr> [options] 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
-respository. It supports any combination of subversion, git, cvs, mecurial and
-bzr repositories, and support for other revision control systems can easily be
-added.
+respository. It supports any combination of subversion, git, cvs, mecurial,
+bzr and darcs repositories, and support for other revision control systems can
+easily be added.
 
 B<mr> cds into and operates on all registered repositories at or below your
 working directory. Or, if you are in a subdirectory of a repository that
@@ -160,10 +160,8 @@ recurse into deeper repositories.
 =item -j number
 
 Run the specified number of jobs in parallel. This can greatly speed up
-operations such as updates.
-
-Note that in -j mode, all output of the jobs goes to standard output, even
-output that would normally go to standard error.
+operations such as updates. It is not recommended for interactive
+operations.
 
 =back
 
@@ -211,7 +209,11 @@ directory, since the repository isn't checked out yet. All other commands
 are run inside the repository, though not necessarily at the top of it.
 
 The "MR_REPO" environment variable is set to the path to the top of the
-repository. The "MR_CONFIG" environment variable is set to the .mrconfig file
+repository. (For the "register" action, "MR_REPO" is instead set to the 
+basename of the directory that should be created when checking the
+repository out.)
+
+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.
 
@@ -231,7 +233,17 @@ mr is run by joey. The second uses the hours_since function
 been at least 12 hours since the last update.
 
   skip = test $(whoami) != joey
-  skip = [ "$1" = update ] && [ $(hours_since "$1") -lt 12 ]
+  skip = [ "$1" = update ] && ! hours_since "$1" 12
+
+=item order
+
+The "order" parameter can be used to override the default ordering of
+repositories. The default order value is 10. Use smaller values to make
+repositories be processed earlier, and larger values to make repositories
+be processed later.
+
+Note that if a repository is located in a subdirectory of another
+repository, ordering it to be processed earlier is not recommended.
 
 =item chain
 
@@ -239,6 +251,15 @@ If the "chain" parameter is set and its command returns true, then B<mr>
 will try to load a .mrconfig file from the root of the repository. (You
 should avoid chaining from repositories with untrusted committers.)
 
+=item include
+
+If the "include" parameter is set, its command is ran, and should output
+additional mrconfig file content. The content is included as if it were
+part of the including file.
+
+Unlike all other parameters, this parameter does not need to be placed
+within a section.
+
 =item lib
 
 The "lib" parameter can specify some shell code that will be run before each
@@ -247,6 +268,18 @@ to use.
 
 =back
 
+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,
+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.
+
 =head1 AUTHOR
 
 Copyright 2007 Joey Hess <joey@kitenet.net>
@@ -278,7 +311,6 @@ $SIG{INT}=sub {
 
 $ENV{MR_CONFIG}="$ENV{HOME}/.mrconfig";
 my $config_overridden=0;
-my $directory=getcwd();
 my $verbose=0;
 my $stats=0;
 my $no_recurse=0;
@@ -287,6 +319,7 @@ my %config;
 my %configfiles;
 my %knownactions;
 my %alias;
+my $directory=getcwd();
 
 Getopt::Long::Configure("no_permute");
 my $result=GetOptions(
@@ -302,6 +335,9 @@ if (! $result || @ARGV < 1) {
 	    "(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
@@ -391,45 +427,81 @@ elsif ($action eq 'register') {
 			next unless length $topdir;
 			if ($directory=~/^\Q$topdir\E/) {
 				$ENV{MR_CONFIG}=$configfiles{$topdir};
+				$directory=$topdir;
 				last;
 			}
 		}
 	}
-	my $command="set -e; ".$config{''}{DEFAULT}{lib}."\n".
-		"my_action(){ $config{''}{DEFAULT}{$action}\n }; my_action ".
+	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", $ENV{MR_REPO}, $directory, 'DEFAULT');
+	if (! defined $command) {
+		die "mr $action: 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 STDERR "mr $action: running >>$command<<\n" if $verbose;
+	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 $topdir (sort keys %config) {
-	foreach my $subdir (sort keys %{$config{$topdir}}) {
+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=~/\/$/;
-		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
-	LEAF: foreach my $topdir (reverse sort keys %config) {
-		foreach my $subdir (reverse sort keys %{$config{$topdir}}) {
-			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 LEAF;
-			}
+		if ($d=~/^\Q$dir\E/) {
+			push @repos, [$dir, $topdir, $subdir];
+			last;
 		}
 	}
 	$nochdir=1;
@@ -469,6 +541,52 @@ elsif (! @ok && @skipped) {
 }
 exit 0;
 
+sub rcs_test { #{{{
+	my ($action, $dir, $topdir, $subdir) = @_;
+
+	my $test="set -e\n";
+	foreach my $rcs_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";
+	}
+	$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 (! length $rcs) {
+		return undef;
+	}
+	else {
+		return $rcs;
+	}
+} #}}}
+	
+sub findcommand { #{{{
+	my ($action, $dir, $topdir, $subdir) = @_;
+	
+	if (exists $config{$topdir}{$subdir}{$action}) {
+		return $config{$topdir}{$subdir}{$action};
+	}
+
+	my $rcs=rcs_test(@_);
+
+	if (defined $rcs && 
+	    exists $config{$topdir}{$subdir}{$rcs."_".$action}) {
+		return $config{$topdir}{$subdir}{$rcs."_".$action};
+	}
+	else {
+		return undef;
+	}
+} #}}}
+
 sub action { #{{{
 	my ($action, $dir, $topdir, $subdir) = @_;
 
@@ -489,17 +607,20 @@ sub action { #{{{
 			system("mkdir", "-p", $dir);
 		}
 	}
-	elsif ($action eq 'update') {
+	elsif ($action =~ /update/) {
 		if (! -d $dir) {
 			return action("checkout", $dir, $topdir, $subdir);
 		}
 	}
-	
+
 	$ENV{MR_REPO}=$dir;
 
-	if (exists $config{$topdir}{$subdir}{skip}) {
+	my $skiptest=findcommand("skip", $dir, $topdir, $subdir);
+	my $command=findcommand($action, $dir, $topdir, $subdir);
+
+	if (defined $skiptest) {
 		my $test="set -e;".$lib.
-			"my_action(){ $config{$topdir}{$subdir}{skip}\n }; my_action '$action'";
+			"my_action(){ $skiptest\n }; my_action '$action'";
 		print "mr $action: running skip test >>$test<<\n" if $verbose;
 		my $ret=system($test);
 		if ($ret != 0) {
@@ -522,23 +643,31 @@ sub action { #{{{
 		print STDERR "mr $action: failed to chdir to $dir: $!\n";
 		return FAILED;
 	}
-	elsif (! exists $config{$topdir}{$subdir}{$action}) {
-		print STDERR "mr $action: no defined $action command for $topdir$subdir, skipping\n";
-		return SKIPPED;
+	elsif (! defined $command) {
+		my $rcs=rcs_test(@_);
+		if (! defined $rcs) {
+			print STDERR "mr $action: unknown repository type and no defined $action command for $topdir$subdir\n";
+			return FAILED;
+		}
+		else {
+			print STDERR "mr $action: no defined $action command for $rcs repository $topdir$subdir, skipping\n";
+			return SKIPPED;
+		}
 	}
 	else {
 		if (! $nochdir) {
 			print "mr $action: $topdir$subdir\n";
 		}
 		else {
-			print "mr $action: $topdir$subdir (in subdir $directory)\n";
+			my $s=$directory;
+			$s=~s/^\Q$topdir$subdir\E\/?//;
+			print "mr $action: $topdir$subdir (in subdir $s)\n";
 		}
-		my $command="set -e; ".$lib.
-			"my_action(){ $config{$topdir}{$subdir}{$action}\n }; my_action ".
+		$command="set -e; ".$lib.
+			"my_action(){ $command\n }; my_action ".
 			join(" ", map { s/\//\/\//g; s/"/\"/g; '"'.$_.'"' } @ARGV);
-		print STDERR "mr $action: running >>$command<<\n" if $verbose;
+		print "mr $action: running >>$command<<\n" if $verbose;
 		my $ret=system($command);
-		print "\n";
 		if ($ret != 0) {
 			if (($? & 127) == 2) {
 				print STDERR "mr $action: interrupted\n";
@@ -569,72 +698,83 @@ sub action { #{{{
 } #}}}
 
 # run actions on multiple repos, in parallel
-my %jobs;
 sub mrs { #{{{
 	$| = 1;
+	my @active;
 	my @fhs;
 	my @out;
 	my $running=0;
 	while (@fhs or @repos) {
 		while ($running < $jobs && @repos) {
-			$SIG{CHLD}='DEFAULT';
 			$running++;
 			my $repo = shift @repos;
-			my $pid = open(my $fh, "-|");
-			if (! $pid) {
-				open(STDERR, ">&STDOUT");
+			pipe(my $outfh, CHILD_STDOUT);
+			pipe(my $errfh, CHILD_STDERR);
+			my $pid;
+			unless ($pid = fork) {
+				die "mr $action: cannot fork: $!" unless defined $pid;
+				open(STDOUT, ">&CHILD_STDOUT") || die "mr $action cannot reopen stdout: $!";
+				open(STDERR, ">&CHILD_STDERR") || die "mr $action cannot reopen stderr: $!";
+				close CHILD_STDOUT;
+				close CHILD_STDERR;
+				close $outfh;
+				close $errfh;
 				exit action($action, @$repo);
 			}
-			$jobs{$pid}=$repo;
-			push @fhs, $fh;
-			push @out, "";
-			$SIG{CHLD}=\&reaper;
-			reaper();
+			close CHILD_STDOUT;
+			close CHILD_STDERR;
+			push @active, [$pid, $repo];
+			push @fhs, [$outfh, $errfh];
+			push @out, ['',     ''];
 		}
-		my ($rin, $rout) = ('','', '');
+		my ($rin, $rout) = ('','');
 		my $nfound;
-		foreach my $x (@fhs) {
-			next unless defined $x;
-			vec($rin, fileno($x), 1) = 1;
+		foreach my $fh (@fhs) {
+			next unless defined $fh;
+			vec($rin, fileno($fh->[0]), 1) = 1 if defined $fh->[0];
+			vec($rin, fileno($fh->[1]), 1) = 1 if defined $fh->[1];
 		}
 		$nfound = select($rout=$rin, undef, undef, 1);
-		foreach my $i (0..$#fhs) {
-			my $fh = $fhs[$i];
-			next unless defined $fh;
-			if (vec($rout, fileno($fh), 1) == 1) {
-				my $r = '';
-				if (sysread($fh, $r, 1024) == 0) {
-					close($fh);
-					$fhs[$i] = undef;
-					$running--;
-					print $out[$i];
-					$out[$i]='';
+		foreach my $channel (0, 1) {
+			foreach my $i (0..$#fhs) {
+				next unless defined $fhs[$i];
+				my $fh = $fhs[$i][$channel];
+				next unless defined $fh;
+				if (vec($rout, fileno($fh), 1) == 1) {
+					my $r = '';
+					if (sysread($fh, $r, 1024) == 0) {
+						close($fh);
+						$fhs[$i][$channel] = undef;
+						if (! defined $fhs[$i][0] &&
+						    ! defined $fhs[$i][1]) {
+						    	waitpid($active[$i][0], 0);
+							print STDOUT $out[$i][0];
+							print STDERR $out[$i][1];
+							record($active[$i][1], $? >> 8);
+						    	splice(@fhs, $i, 1);
+						    	splice(@active, $i, 1);
+						    	splice(@out, $i, 1);
+							$running--;
+						}
+					}
+					$out[$i][$channel] .= $r;
 				}
-				$out[$i] .= $r;
 			}
 		}
-		while (@fhs and !defined $fhs[0]) {
-			shift @fhs;
-			shift @out;
-		}
 	}
 } #}}}
 
-sub reaper { #{{{
-	while ((my $pid = waitpid(-1, &WNOHANG)) > 0) {
-		record($jobs{$pid}, $? >> 8) if exists $jobs{$pid};
-	}
-} #}}}
-		
 sub record { #{{{
 	my $dir=shift()->[0];
 	my $ret=shift;
 
 	if ($ret == OK) {
 		push @ok, $dir;
+		print "\n";
 	}
 	elsif ($ret == FAILED) {
 		push @failed, $dir;
+		print "\n";
 	}
 	elsif ($ret == SKIPPED) {
 		push @skipped, $dir;
@@ -731,6 +871,12 @@ sub loadconfig { #{{{
 				chomp $value;
 			}
 
+			if ($parameter eq "include") {
+				print "mr: including output of \"$value\"\n" if $verbose;
+				unshift @lines, `$value`;
+				next;
+			}
+
 			if (! defined $section) {
 				die "$f line $.: parameter ($parameter) not in section\n";
 			}
@@ -748,7 +894,12 @@ sub loadconfig { #{{{
 			}
 			else {
 				$config{$dir}{$section}{$parameter}=$value;
-				$knownactions{$parameter}=1;
+				if ($parameter =~ /.*_(.*)/) {
+					$knownactions{$1}=1;
+				}
+				else {
+					$knownactions{$parameter}=1;
+				}
 				if ($parameter eq 'chain' &&
 				    length $dir && $section ne "DEFAULT" &&
 				    -e $dir.$section."/.mrconfig") {
@@ -885,13 +1036,23 @@ ci = commit
 ls = list
 
 [DEFAULT]
+order = 10
 lib =
 	error() {
 		echo "mr: $@" >&2
 		exit 1
 	}
+	warning() {
+		echo "mr (warning): $@" >&2
+	}
+	info() {
+		echo "mr: $@" >&2
+	}
 	hours_since() {
-		for dir in .git .svn .bzr CVS .hg; do
+		if [ -z "$1" ] || [ -z "$2" ]; then
+			error "mr: usage: hours_since action num"
+		fi
+		for dir in .git .svn .bzr CVS .hg _darcs; do
 			if [ -e "$MR_REPO/$dir" ]; then
 				flagfile="$MR_REPO/$dir/.mr_last$1"
 				break
@@ -900,127 +1061,107 @@ lib =
 		if [ -z "$flagfile" ]; then
 			error "cannot determine flag filename"
 		fi
-		perl -wle 'print -f shift() ? int((-M _) * 24) : 9999' "$flagfile"
-		touch "$flagfile"
-	}
-
-update =
-	if [ -d "$MR_REPO"/.svn ]; then
-		svn update "$@"
-	elif [ -d "$MR_REPO"/.git ]; then
-		if [ -z "$@" ]; then
-			git pull -t origin master
+		delta=$(perl -wle 'print -f shift() ? int((-M _) * 24) : 9999' "$flagfile")
+		if [ "$delta" -lt "$2" ]; then
+			exit 0
 		else
-			git pull "$@"
+			touch "$flagfile"
+			exit 1
 		fi
-	elif [ -d "$MR_REPO"/.bzr ]; then
-		bzr merge "$@"
-	elif [ -d "$MR_REPO"/CVS ]; then
-		cvs update "$@"
-	elif [ -d "$MR_REPO"/.hg ]; then
-		hg pull "$@" && hg update "$@"
-	else
-		error "unknown repo type"
-	fi
-status =
-	if [ -d "$MR_REPO"/.svn ]; then
-		svn status "$@"
-	elif [ -d "$MR_REPO"/.git ]; then
-		git status "$@" || true
-	elif [ -d "$MR_REPO"/.bzr ]; then
-		bzr status "$@"
-	elif [ -d "$MR_REPO"/CVS ]; then
-		cvs status "$@"
-	elif [ -d "$MR_REPO"/.hg ]; then
-		hg status "$@"
-	else
-		error "unknown repo type"
-	fi
-commit =
-	if [ -d "$MR_REPO"/.svn ]; then
-		svn commit "$@"
-	elif [ -d "$MR_REPO"/.git ]; then
-		git commit -a "$@" && git push --all
-	elif [ -d "$MR_REPO"/.bzr ]; then
-		bzr commit "$@" && bzr push
-	elif [ -d "$MR_REPO"/CVS ]; then
-		cvs commit "$@"
-	elif [ -d "$MR_REPO"/.hg ]; then
-		hg commit -m "$@" && hg push
-	else
-		error "unknown repo type"
-	fi
-diff =
-	if [ -d "$MR_REPO"/.svn ]; then
-		svn diff "$@"
-	elif [ -d "$MR_REPO"/.git ]; then
-		git diff "$@"
-	elif [ -d "$MR_REPO"/.bzr ]; then
-		bzr diff "$@"
-	elif [ -d "$MR_REPO"/CVS ]; then
-		cvs diff "$@"
-	elif [ -d "$MR_REPO"/.hg ]; then
-		hg diff "$@"
-	else
-		error "unknown repo type"
+	}
+
+svn_test = test -d "$MR_REPO"/.svn
+git_test = test -d "$MR_REPO"/.git
+bzr_test = test -d "$MR_REPO"/.bzr
+cvs_test = test -d "$MR_REPO"/CVS
+hg_test  = test -d "$MR_REPO"/.hg
+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
+
+svn_update = svn update "$@"
+git_update = if [ "$@" ]; then git pull "$@"; else git pull -t origin master; fi
+bzr_update = bzr merge "$@"
+cvs_update = cvs update "$@"
+hg_update  = hg pull "$@" && hg update "$@"
+darcs_update = darcs pull -a "$@"
+
+svn_status = svn status "$@"
+git_status = git status "$@" || true
+bzr_status = bzr status "$@"
+cvs_status = cvs status "$@"
+hg_status  = hg status "$@"
+darcs_status = darcs whatsnew -ls "$@"
+
+svn_commit = svn commit "$@"
+git_commit = git commit -a "$@" && git push --all
+bzr_commit = bzr commit "$@" && bzr push
+cvs_commit = cvs commit "$@"
+hg_commit  = hg commit -m "$@" && hg push
+darcs_commit = darcs commit -a -m "$@" && darcs push -a
+
+svn_diff = svn diff "$@"
+git_diff = git diff "$@"
+bzr_diff = bzr diff "$@"
+cvs_diff = cvs diff "$@"
+hg_diff  = hg diff "$@"
+darcs_diff = darcs diff "$@"
+
+svn_log = svn log "$@"
+git_log = git log "$@"
+bzr_log = bzr log "$@"
+cvs_log = cvs log "$@"
+hg_log  = hg log "$@"
+darcs_log = darcs changes "$@"
+git_bare_log = git log "$@"
+
+svn_register =
+	url=$(LANG=C svn info . | grep -i ^URL: | cut -d ' ' -f 2)
+	if [ -z "$url" ]; then
+		error "cannot determine svn url"
 	fi
-log =
-	if [ -d "$MR_REPO"/.svn ]; then
-		svn log"$@"
-	elif [ -d "$MR_REPO"/.git ]; then
-		git log "$@"
-	elif [ -d "$MR_REPO"/.bzr ]; then
-		bzr log "$@"
-	elif [ -d "$MR_REPO"/CVS ]; then
-		cvs log "$@"
-	elif [ -d "$MR_REPO"/.hg ]; then
-		hg log "$@"
-	else
-		error "unknown repo type"
+	echo "Registering svn url: $url in $MR_CONFIG"
+	mr -c "$MR_CONFIG" config "`pwd`" checkout="svn co '$url' '$MR_REPO'"
+git_register = 
+	url="$(LANG=C git-config --get remote.origin.url)" || true
+	if [ -z "$url" ]; then
+		error "cannot determine git url"
 	fi
-register =
-	if [ -n "$1" ]; then
-		cd "$1"
+	echo "Registering git url: $url in $MR_CONFIG"
+	mr -c "$MR_CONFIG" config "`pwd`" checkout="git clone '$url' '$MR_REPO'"
+bzr_register =
+	url=$(cat .bzr/branch/parent)
+	if [ -z "$url" ]; then
+		error "cannot determine bzr url"
 	fi
-	basedir="$(basename $(pwd))"
-	if [ -d .svn ]; then
-		url=$(LANG=C svn info . | grep -i ^URL: | cut -d ' ' -f 2)
-		if [ -z "$url" ]; then
-			error "cannot determine svn url"
+	echo "Registering bzr url: $url in $MR_CONFIG"
+	mr -c "$MR_CONFIG" config "`pwd`" checkout="bzr clone '$url' '$MR_REPO'"
+cvs_register =
+	repo=$(cat CVS/Repository)
+	root=$(cat CVS/Root)
+	if [ -z "$root" ]; then
+		error "cannot determine cvs root"
 		fi
-		echo "Registering svn url: $url in $MR_CONFIG"
-		mr -c "$MR_CONFIG" config "$(pwd)" checkout="svn co $url $basedir"
-	elif [ -d .git ]; then
-		url=$(LANG=C git-config --get remote.origin.url)
-		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 $basedir"
-	elif [ -d .bzr ]; then
-		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 $basedir"
-	elif [ -d CVS ]; then
-		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 $basedir $repo"
-	elif [ -d .hg ]; then
-		url=$(hg showconfig paths.default)
-		echo "Registering mercurial repo url: $url in $MR_CONFIG"
-		mr -c "$MR_CONFIG" config "$(pwd)" \
-			checkout="hg clone $url $basedir"
-	else
-		error "unable to register this repo type"
+	echo "Registering cvs repository $repo at root $root"
+	mr -c "$MR_CONFIG" config "`pwd`" checkout="cvs -d '$root' co -d '$MR_REPO' '$repo'"
+hg_register = 
+	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'"
+darcs_register = 
+	url=$(cat _darcs/prefs/defaultrepo)
+	echo "Registering darcs repository $url in $MR_CONFIG"
+	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
+	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'"
+
 help =
 	if [ ! -e "$MR_PATH" ]; then
 		error "cannot find program path"
@@ -1033,3 +1174,5 @@ ed = echo "A horse is a horse, of course, of course.."
 T = echo "I pity the fool."
 right = echo "Not found."
 #}}}
+
+# vim:sw=8:sts=0:ts=8:noet