]> git.madduck.net Git - code/myrepos.git/commitdiff

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:

VCS_dir_test optmisation
authorJoey Hess <joey@kitenet.net>
Mon, 5 Dec 2011 21:55:15 +0000 (17:55 -0400)
committerJoey Hess <joey@kitenet.net>
Mon, 5 Dec 2011 21:55:15 +0000 (17:55 -0400)
This reduces mr list to run in just 2 seconds here. Nearly all that runtime
involves running my many skip tests.

In the d-i tree, mr list used to take 4.55 seconds, and now takes only
0.47 seconds!

mr

diff --git a/mr b/mr
index 38bf2b779306063440b13aeb5fd487c714c93c99..1923506a42cf4522e403d23f9cd63e01d46b42dd 100755 (executable)
--- a/mr
+++ b/mr
@@ -435,9 +435,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
 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
 
 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 +455,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.
 
 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
 =back
 
 =head1 UNTRUSTED MRCONFIG FILES
@@ -575,7 +585,17 @@ sub runsh {
        $runner->($shellcode);
 }
 
        $runner->($shellcode);
 }
 
+sub runshpipe {
+       runsh @_, sub {
+               my $sh=shift;
+               my $ret=`$sh`;
+               chomp $ret;
+               return $ret;
+       };
+}
+
 my %vcs;
 my %vcs;
+my %vcs_dir_test;
 sub vcs_test {
        my ($action, $dir, $topdir, $subdir) = @_;
 
 sub vcs_test {
        my ($action, $dir, $topdir, $subdir) = @_;
 
@@ -584,23 +604,43 @@ sub vcs_test {
        }
 
        my $test="";
        }
 
        my $test="";
+       my $dir_test="";
        foreach my $vcs_test (
                        sort {
                                length $a <=> length $b 
                                          ||
                                       $a cmp $b
                        } grep { /_test$/ } keys %{$config{$topdir}{$subdir}}) {
        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";
        }
 
                $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";
        if ($vcs=~/\n/s) {
                $vcs=~s/\n/, /g;
                print STDERR "mr $action: found multiple possible repository types ($vcs) for ".fulldir($topdir, $subdir)."\n";
@@ -1815,12 +1855,12 @@ lib =
                fi
        }
 
                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 &&
 fossil_test = test -f "$MR_REPO"/_FOSSIL_
 git_bare_test =
        test -d "$MR_REPO"/refs/heads && test -d "$MR_REPO"/refs/tags &&