command, this can be a useful way to define shell functions for other commands
to use.
+=item fixups
+
+If the "fixups" parameter is set, its command is run whenever a repository
+is checked out, or updated. This provides an easy way to do things
+like permissions fixups, or other tweaks to the repository content,
+whenever the repository is changed.
+
+=item pre_ and post_
+
+If a "pre_action" parameter is set, its command is run before mr performs the
+specified action. Similarly, "post_action" parameters are run after mr
+successfully performs the specified action. For example, "pre_commit" is
+run before committing; "post_update" is run after updating.
+
=back
When looking for a command to run for a given action, mr first looks for
my $lib=exists $config{$topdir}{$subdir}{lib} ?
$config{$topdir}{$subdir}{lib}."\n" : "";
my $is_checkout=($action eq 'checkout');
+ my $is_update=($action =~ /update/);
$ENV{MR_REPO}=$dir;
$dir=~s/^(.*)\/[^\/]+\/?$/$1/;
}
}
- elsif ($action =~ /update/) {
+ elsif ($is_update) {
if (! -d $dir) {
return action("checkout", $dir, $topdir, $subdir);
}
$s=~s/^\Q$topdir$subdir\E\/?//;
print "mr $action: $topdir$subdir (in subdir $s)\n" unless $quiet;
}
+
+ my $hookret=hook("pre_$action", $topdir, $subdir);
+ return $hookret if $hookret != OK;
+
$command="set -e; ".$lib.
"my_action(){ $command\n }; my_action ".
join(" ", map { s/\//\/\//g; s/"/\"/g; '"'.$_.'"' } @ARGV);
return FAILED;
}
else {
- if ($action eq 'checkout' && ! -d $dir) {
+ if ($is_checkout && ! -d $dir) {
print STDERR "mr $action: $dir missing after checkout\n";;
return FAILED;
}
+ my $ret=hook("post_$action", $topdir, $subdir);
+ return $ret if $ret != OK;
+
+ if (($is_checkout || $is_update)) {
+ my $ret=hook("fixups", $topdir, $subdir);
+ return $ret if $ret != OK;
+ }
+
return OK;
}
}
}
+sub hook {
+ my ($hook, $topdir, $subdir) = @_;
+
+ my $command=$config{$topdir}{$subdir}{$hook};
+ return OK unless defined $command;
+ my $lib=exists $config{$topdir}{$subdir}{lib} ?
+ $config{$topdir}{$subdir}{lib}."\n" : "";
+ my $shell="set -e;".$lib.
+ "my_hook(){ $command\n }; my_hook";
+ print "mr $hook: running >>$shell<<\n" if $verbose;
+ my $ret=system($shell);
+ if ($ret != 0) {
+ if (($? & 127) == 2) {
+ print STDERR "mr $hook: interrupted\n";
+ return ABORT;
+ }
+ elsif ($? & 127) {
+ print STDERR "mr $hook: received signal ".($? & 127)."\n";
+ return ABORT;
+ }
+ }
+
+ return OK;
+}
+
# run actions on multiple repos, in parallel
sub mrs {
my $action=shift;
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
fossil_test = test -f "$MR_REPO"/_FOSSIL_
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
-darcs_test = test -d "$MR_REPO"/_darcs
svn_update = svn update "$@"
git_update = git pull "$@"
bzr_record = bzr commit "$@"
hg_record = hg commit -m "$@"
darcs_record = darcs record -a -m "$@"
-fossil_record = git commit "$@"
+fossil_record = fossil commit "$@"
svn_push = :
git_push = git push "$@"
mr -c "$MR_CONFIG" config "`pwd`" checkout="git clone --bare '$url' '$MR_REPO'"
fossil_register =
url=`fossil remote-url`
- repo=`fossil info | grep repository | sed -e s/repository:*.//g -e s/\ //g`
+ repo=`fossil info | grep repository | sed -e 's/repository:*.//g' -e 's/ //g'`
echo "Registering fossil repository $url in $MR_CONFIG"
mr -c "$MR_CONFIG" config "`pwd`" checkout="mkdir -p '$MR_REPO' && cd '$MR_REPO' && fossil open '$repo'"