]>
git.madduck.net Git - code/myrepos.git/blobdiff - mr
madduck's git repository
Every one of the projects in this repository is available at the canonical
URL git://git.madduck.net/madduck/pub/<projectpath> — see
each project's metadata for the exact URL.
All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@ git. madduck. net .
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
SSH access, as well as push access can be individually
arranged .
If you use my repositories frequently, consider adding the following
snippet to ~/.gitconfig and using the third clone URL listed for each
project:
[url "git://git.madduck.net/madduck/"]
insteadOf = madduck:
=head1 NAME
mr - a Multiple Repository management tool
=head1 NAME
mr - a Multiple Repository management tool
-B<mr> is a Multiple Repository management tool. It allows you to register a
-set of repositories in a .mrconfig file, and then checkout, update, or
-perform other actions on the repositories as if they were one big
-respository.
-
-Any mix of revision control systems can be used with B<mr>, and you can
-define arbitrary actions for commands like "update", "checkout", or "commit".
+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, and bzr repositories,
+and support for other revision control systems can easily be added.
B<mr> cds into and operates on all registered repsitories at or below your
working directory. Or, if you are in a subdirectory of a repository that
contains no other registered repositories, it will stay in that directory,
and work on only that repository,
B<mr> cds into and operates on all registered repsitories at or below your
working directory. Or, if you are in a subdirectory of a repository that
contains no other registered repositories, it will stay in that directory,
and work on only that repository,
-The predefined commands should be fairly familiar to users of any revision
+These predefined commands should be fairly familiar to users of any revision
+=back
+
+These commands are also available:
+
+=over 4
+
=item list (or ls)
List the repositories that mr will act on.
=item list (or ls)
List the repositories that mr will act on.
+=item -s
+
+Expand the statistics line displayed at the end to include information
+about exactly which repositories failed and were skipped, if any.
+
use warnings;
use strict;
use Getopt::Long;
use warnings;
use strict;
use Getopt::Long;
my $directory=getcwd();
my $config="$ENV{HOME}/.mrconfig";
my $verbose=0;
my $directory=getcwd();
my $config="$ENV{HOME}/.mrconfig";
my $verbose=0;
my %config;
my %knownactions;
my %alias;
my %config;
my %knownactions;
my %alias;
my $result=GetOptions(
"d|directory=s" => sub { $directory=abs_path($_[1]) },
"c|config=s" => \$config,
my $result=GetOptions(
"d|directory=s" => sub { $directory=abs_path($_[1]) },
"c|config=s" => \$config,
- "verbose" => \$verbose,
+ "v|verbose" => \$verbose,
+ "s|stats" => \$stats,
);
if (! $result || @ARGV < 1) {
die("Usage: mr [-d directory] action [params ...]\n".
);
if (! $result || @ARGV < 1) {
die("Usage: mr [-d directory] action [params ...]\n".
-my (@failed, @successful , @skipped);
+my (@failed, @ok , @skipped);
foreach my $repo (@repos) {
action($action, @$repo);
}
foreach my $repo (@repos) {
action($action, @$repo);
}
my ($action, $dir, $topdir, $subdir) = @_;
my $lib= exists $config{$topdir}{$subdir}{lib} ?
my ($action, $dir, $topdir, $subdir) = @_;
my $lib= exists $config{$topdir}{$subdir}{lib} ?
- push @successful , $dir;
my $count=shift;
my $singular=shift;
my $plural=shift;
my $count=shift;
my $singular=shift;
my $plural=shift;
return "$count ".($count > 1 ? $plural : $singular);
}
return;
return "$count ".($count > 1 ? $plural : $singular);
}
return;
-}
-if (! @successful && ! @failed && ! @skipped) {
+} #}}}
+if (! @ok && ! @failed && ! @skipped) {
die "mr $action: no repositories found to work on\n";
}
print "mr $action: finished (".join("; ",
die "mr $action: no repositories found to work on\n";
}
print "mr $action: finished (".join("; ",
- showstat($#successful+1, "successful", "successful "),
+ showstat($#ok+1, "ok", "ok "),
showstat($#failed+1, "failed", "failed"),
showstat($#skipped+1, "skipped", "skipped"),
).")\n";
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 "mr $action: (failed: ".join(" ", @failed).")\n";
+ }
+}
-elsif (! @successful && @skipped) {
+elsif (! @ok && @skipped) {
exit 1;
}
exit 0;
my %loaded;
exit 1;
}
exit 0;
my %loaded;
# copy in defaults from first parent
my $parent=$dir;
# copy in defaults from first parent
my $parent=$dir;
- while ($parent=~s/^(.*)\/[^\/]+\/?$/$1/) {
+ while ($parent=~s/^(.*\/)[^\/]+\/?$/$1/) {
+ if ($parent eq '/') {
+ $parent="";
+ }
if (exists $config{$parent} &&
exists $config{$parent}{DEFAULT}) {
$config{$dir}{DEFAULT}={ %{$config{$parent}{DEFAULT}} };
if (exists $config{$parent} &&
exists $config{$parent}{DEFAULT}) {
$config{$dir}{DEFAULT}={ %{$config{$parent}{DEFAULT}} };
while (@lines) {
$_=shift @lines;
while (@lines) {
$_=shift @lines;
chomp;
next if /^\s*\#/ || /^\s*$/;
if (/^\[([^\]]*)\]\s*$/) {
chomp;
next if /^\s*\#/ || /^\s*$/;
if (/^\[([^\]]*)\]\s*$/) {
# continued value
while (@lines && $lines[0]=~/^\s(.+)/) {
shift(@lines);
# continued value
while (@lines && $lines[0]=~/^\s(.+)/) {
shift(@lines);
$value.="\n$1";
chomp $value;
}
$value.="\n$1";
chomp $value;
}
- die "$f line $. : parse error\n";
+ die "$f line $line : parse error\n";
}
}
foreach (@toload) {
loadconfig($_);
}
}
}
foreach (@toload) {
loadconfig($_);
}
my $f=shift;
# the section to modify or add
my $targetsection=shift;
my $f=shift;
# the section to modify or add
my $targetsection=shift;
open(my $out, ">", $f) || die "mr: write $f: $!\n";
print $out @out;
close $out;
open(my $out, ">", $f) || die "mr: write $f: $!\n";
print $out @out;
close $out;
# Finally, some useful actions that mr knows about by default.
# These can be overridden in ~/.mrconfig.
# Finally, some useful actions that mr knows about by default.
# These can be overridden in ~/.mrconfig.
__DATA__
[ALIAS]
co = checkout
__DATA__
[ALIAS]
co = checkout
ed = echo "A horse is a horse, of course, of course.."
T = echo "I pity the fool."
ed = echo "A horse is a horse, of course, of course.."
T = echo "I pity the fool."
+right = echo "Not found."
+#}}}