X-Git-Url: https://git.madduck.net/code/myrepos.git/blobdiff_plain/9a9cbb453427926f2f658734285f6305c7502afb..552a9560c671c36ca527da4c4a51369633e3960f:/mr?ds=sidebyside diff --git a/mr b/mr index bb98ba6..e76887e 100755 --- a/mr +++ b/mr @@ -7,7 +7,7 @@ mr - a Multiple Repository management tool =head1 SYNOPSIS - +/ B [options] checkout B [options] update @@ -28,6 +28,10 @@ B [options] config section ["parameter=[value]" ...] B [options] action [params ...] +B [options] [online|offline] + +B [options] remember action [params ...] + =head1 DESCRIPTION B is a Multiple Repository management tool. It can checkout, update, or @@ -77,6 +81,11 @@ remote repository. Only supported for distributed revision 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. + =item diff Show a diff of uncommitted changes. @@ -126,6 +135,24 @@ To see the built-in library of shell functions contained in mr: The ~/.mrconfig file is used by default. To use a different config file, use the -c option. +=item offline + +Advises mr that it is in offline mode. Any commands that fail in +offline mode will be remembered, and retried when mr is told it's online. + +=item online + +Advices mr that it is in online mode again. Commands that failed while in +offline mode will be re-run. + +=item remember + +Remember a command, to be run later when mr re-enters online mode. This +implicitly puts mr into offline mode. The command can be any regular mr +command. This is useful when you know that a command will fail due to being +offline, and so don't want to run it right now at all, but just remember +to run it when you go back online. + =item help Displays this help. @@ -196,6 +223,11 @@ a good speedup in updates without loading the machine too much. =head1 FILES +The ~/.mrlog file contains commands that mr has remembered to run later, +due to being offline. You can delete or edit this file to remove commands, +or even to add other commands for 'mr online' to run. If the file is +present, mr assumes it is in offline mode. + B is configured by .mrconfig files. It starts by reading the .mrconfig file in your home directory, and this can in turn chain load .mrconfig files from repositories. @@ -425,6 +457,8 @@ sub action { #{{{ $config{$topdir}{$subdir}{lib}."\n" : ""; my $is_checkout=($action eq 'checkout'); + $ENV{MR_REPO}=$dir; + if ($is_checkout) { if (-d $dir) { print "mr $action: $dir already exists, skipping checkout\n" if $verbose; @@ -439,8 +473,6 @@ sub action { #{{{ } } - $ENV{MR_REPO}=$dir; - my $skiptest=findcommand("skip", $dir, $topdir, $subdir, $is_checkout); my $command=findcommand($action, $dir, $topdir, $subdir, $is_checkout); @@ -511,6 +543,12 @@ sub action { #{{{ print STDERR "mr $action: failed ($ret)\n" if $verbose; if ($ret >> 8 != 0) { print STDERR "mr $action: command failed\n"; + if (-e "$ENV{HOME}/.mrlog" && $action ne 'remember') { + # recreate original command line to + # remember, and avoid recursing + @ARGV=('-n', $action, @ARGV); + action("remember", $dir, $topdir, $subdir); + } } elsif ($ret != 0) { print STDERR "mr $action: command died ($ret)\n"; @@ -973,6 +1011,13 @@ sub dispatch { #{{{ elsif ($action eq 'register') { register(@ARGV); } + elsif ($action eq 'remember' || + $action eq 'offline' || + $action eq 'online') { + my @repos=selectrepos; + action($action, @{$repos[0]}) if @repos; + exit 0; + } if (!$jobs || $jobs > 1) { mrs($action, selectrepos()); @@ -987,7 +1032,7 @@ sub dispatch { #{{{ sub help { #{{{ exec($config{''}{DEFAULT}{help}) || die "exec: $!"; } #}}} - + sub config { #{{{ if (@_ < 2) { die "mr config: not enough parameters\n"; @@ -1027,7 +1072,12 @@ sub config { #{{{ } #}}} sub register { #{{{ - if (! $config_overridden) { + if ($config_overridden) { + # Find the directory that the specified config file is + # located in. + ($directory)=abs_path($ENV{MR_CONFIG})=~/^(.*\/)[^\/]+$/; + } + else { # Find the closest known mrconfig file to the current # directory. $directory.="/" unless $directory=~/\/$/; @@ -1091,6 +1141,7 @@ sub expandaction { #{{{ } #}}} sub getopts { #{{{ + my @saved=@ARGV; Getopt::Long::Configure("bundling", "no_permute"); my $result=GetOptions( "d|directory=s" => sub { $directory=abs_path($_[1]) }, @@ -1106,6 +1157,12 @@ sub getopts { #{{{ die("Usage: mr [-d directory] action [params ...]\n". "(Use mr help for man page.)\n"); } + + $ENV{MR_SWITCHES}=""; + foreach my $option (@saved) { + last if $option eq $ARGV[0]; + $ENV{MR_SWITCHES}.="$option "; + } } #}}} sub init { #{{{ @@ -1135,10 +1192,11 @@ sub init { #{{{ 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); @@ -1235,6 +1293,13 @@ bzr_record = bzr commit "$@" hg_record = hg commit -m "$@" darcs_record = darcs record -a -m "$@" +svn_push = : +git_push = git push "$@" +bzr_push = bzr push "$@" +cvs_push = : +hg_push = hg push "$@" +darcs_push = darcs push -a + svn_diff = svn diff "$@" git_diff = git diff "$@" bzr_diff = bzr diff "$@" @@ -1306,6 +1371,30 @@ help = list = true config = +online = + if [ -s ~/.mrlog ]; then + info "running offline commands" + mv -f ~/.mrlog ~/.mrlog.old + if ! sh -e ~/.mrlog.old; then + error "offline command failed; left in ~/.mrlog.old" + fi + rm -f ~/.mrlog.old + else + info "no offline commands to run" + fi +offline = + touch ~/.mrlog + info "offline mode enabled" +remember = + info "remembering command: 'mr $@'" + command="mr -d '$(pwd)' $MR_SWITCHES" + for w in "$@"; do + command="$command '$w'" + done + if [ ! -e ~/.mrlog ] || ! grep -q -F "$command" ~/.mrlog; then + echo "$command" >> ~/.mrlog + fi + ed = echo "A horse is a horse, of course, of course.." T = echo "I pity the fool." right = echo "Not found."