X-Git-Url: https://git.madduck.net/code/myrepos.git/blobdiff_plain/48204df369a5931a4bf3c9e153e54727ada7c9f1..09af48cd838965e18f3b408d931fd0c8c44a16aa:/mr diff --git a/mr b/mr index 38bf2b7..23178a5 100755 --- a/mr +++ b/mr @@ -212,6 +212,13 @@ Use the specified mrconfig file. The default is to use both F<~/.mrconfig> as well as look for a F<.mrconfig> file in the current directory, or in one of its parent directories. +=item -f + +=item --force + +Force mr to act on repositories that would normally be skipped due to their +configuration. + =item -v =item --verbose @@ -367,7 +374,7 @@ been at least 12 hours since the last update. Another way to use skip is for a lazy checkout. This makes mr skip operating on a repo unless it already exists. To enable the -repo, you have to explicitly check it out (using "mr -d foo checkout"). +repo, you have to explicitly check it out (using "mr --force -d foo checkout"). [foo] checkout = ... @@ -435,9 +442,7 @@ whenever the repository is changed. 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 "VCS_action" (substituting in the name of the -version control system and the action). The name of the version control -system is itself determined by running each defined "VCS_test" action, -until one succeeds. +version control system and the action). Internally, mr has settings for "git_update", "svn_update", etc. To change the action that is performed for a given version control system, you can @@ -457,6 +462,18 @@ Any parameter can be suffixed with C<_append>, to add an additional value to the existing value of the parameter. In this way, actions can be constructed accumulatively. +=item VCS_test + +The name of the version control system is itself determined by +running each defined "VCS_test" action, until one succeeds. + +=item VCS_dir_test + +This is a more optimised way to test for the version control system. +Each "VCS_dir_test" action is run once, and can output lines consisting +of the name of a VCS, and a directory to look for in the top of a repo +to detect that VCS. + =back =head1 UNTRUSTED MRCONFIG FILES @@ -520,6 +537,7 @@ my $config_overridden=0; my $verbose=0; my $quiet=0; my $stats=0; +my $force=0; my $insecure=0; my $interactive=0; my $max_depth; @@ -528,6 +546,7 @@ my $jobs=1; my $trust_all=0; my $directory=getcwd(); +my $HOME_MR_CONFIG = "$ENV{HOME}/.mrconfig"; $ENV{MR_CONFIG}=find_mrconfig(); # globals :-( @@ -575,7 +594,17 @@ sub runsh { $runner->($shellcode); } +sub runshpipe { + runsh @_, sub { + my $sh=shift; + my $ret=`$sh`; + chomp $ret; + return $ret; + }; +} + my %vcs; +my %vcs_dir_test; sub vcs_test { my ($action, $dir, $topdir, $subdir) = @_; @@ -584,23 +613,43 @@ sub vcs_test { } my $test=""; + my $dir_test=""; foreach my $vcs_test ( sort { length $a <=> length $b || $a cmp $b } grep { /_test$/ } keys %{$config{$topdir}{$subdir}}) { - my ($vcs)=$vcs_test=~/(.*)_test/; + if ($vcs_test =~ /(.*)_dir_test/) { + my $vcs=$1; + if (! defined $vcs_dir_test{$vcs}) { + $dir_test.=$config{$topdir}{$subdir}{$vcs_test}."\n"; + } + next; + } + my ($vcs)=$vcs_test =~ /(.*)_test/; $test="my_$vcs_test() {\n$config{$topdir}{$subdir}{$vcs_test}\n}\n".$test; $test.="if my_$vcs_test; then echo $vcs; fi\n"; } - my $vcs=runsh "vcs test", $topdir, $subdir, $test, [], sub { - my $sh=shift; - my $ret=`$sh`; - chomp $ret; - return $ret; - }; + if (length $dir_test) { + runsh "vcs dir test", $topdir, $subdir, $dir_test, [], sub { + my $sh=shift; + foreach my $line (`$sh`) { + chomp $line; + my ($vcs, $dir)=split(" ", $line); + $vcs_dir_test{$vcs}=$dir; + } + } + } + + foreach my $vcs (keys %vcs_dir_test) { + if (-d "$ENV{MR_REPO}/$vcs_dir_test{$vcs}") { + return $vcs{$dir}=$vcs; + } + } + + my $vcs=runshpipe "vcs test", $topdir, $subdir, $test, []; if ($vcs=~/\n/s) { $vcs=~s/\n/, /g; print STDERR "mr $action: found multiple possible repository types ($vcs) for ".fulldir($topdir, $subdir)."\n"; @@ -653,6 +702,8 @@ sub action { $ENV{MR_ACTION}=$action; foreach my $testname ("skip", "deleted") { + next if $force && $testname eq "skip"; + my $testcommand=findcommand($testname, $dir, $topdir, $subdir, $is_checkout); if (defined $testcommand) { @@ -1052,14 +1103,14 @@ sub is_trusted_config { my $config=shift; # must be abs_pathed already # We always trust ~/.mrconfig. - return 1 if $config eq abs_path("$ENV{HOME}/.mrconfig"); + return 1 if $config eq abs_path($HOME_MR_CONFIG); return 1 if $trust_all; my $trustfile=$ENV{HOME}."/.mrtrust"; if (! %trusted) { - $trusted{"$ENV{HOME}/.mrconfig"}=1; + $trusted{$HOME_MR_CONFIG}=1; if (open (TRUST, "<", $trustfile)) { while () { chomp; @@ -1682,7 +1733,7 @@ sub find_mrconfig { } $dir=~s/\/[^\/]*$//; } - return "$ENV{HOME}/.mrconfig"; + return $HOME_MR_CONFIG; } sub getopts { @@ -1692,6 +1743,7 @@ sub getopts { "d|directory=s" => sub { $directory=abs_path($_[1]) }, "c|config=s" => sub { $ENV{MR_CONFIG}=$_[1]; $config_overridden=1 }, "p|path" => sub { }, # now default, ignore + "f|force" => \$force, "v|verbose" => \$verbose, "q|quiet" => \$quiet, "s|stats" => \$stats, @@ -1751,7 +1803,7 @@ sub main { init(); startingconfig(); - loadconfig("$ENV{HOME}/.mrconfig"); + loadconfig($HOME_MR_CONFIG); loadconfig($ENV{MR_CONFIG}); #use Data::Dumper; print Dumper(\%config); @@ -1808,19 +1860,19 @@ lib = LANG=C bzr info | egrep -q '^Checkout' } lazy() { - if [ "$MR_ACTION" = checkout ] || [ -d "$MR_REPO" ]; then + if [ -d "$MR_REPO" ]; then return 1 else return 0 fi } -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 +svn_dir_test = echo svn .svn +git_dir_test = echo git .git +bzr_dir_test = echo bzr .bzr +cvs_dir_test = echo cvs CVS +hg_dir_test = echo hg .hg +darcs_dir_test = echo darcs _darcs fossil_test = test -f "$MR_REPO"/_FOSSIL_ git_bare_test = test -d "$MR_REPO"/refs/heads && test -d "$MR_REPO"/refs/tags &&