]> Sergey Matveev's repositories - public-inbox.git/commitdiff
git: shorten --git-dir= in CLI with chdir in spawn
authorEric Wong <e@80x24.org>
Wed, 29 Sep 2021 21:25:20 +0000 (21:25 +0000)
committerEric Wong <e@80x24.org>
Wed, 29 Sep 2021 21:37:46 +0000 (21:37 +0000)
Long pathnames are difficult to read and distinguish in ps(1)
output.  Deep paths can also slow down pathname resolution
when dealing with loose objects, so we put "cat-file --batch"
deeper into the directory tree.

Since v2 processes are in the form of $INBOXDIR/all.git, keep
the basename of $INBOXDIR in --git-dir= so it's easy to
distinguish between processes just by looking at ps(1).

While "git -C" also exists, it's only present in git 1.8.5+.
We also need to keep in mind the "directory" pointed to by
--git-dir= need not be a directory (nor a symlink pointing
to one).

This reduces pathname resolution overhead for v1 and v2 inbox
git processes, but unfortunately not for extindex since that
needs to store alternates as absolute paths.

lib/PublicInbox/Git.pm

index d5b1d39d148798b477300d119464c5408cb1e088..97c39aad7468a09db5c0a1a5f68d852745f61a2d 100644 (file)
@@ -62,6 +62,8 @@ sub git_quote ($) {
 
 sub new {
        my ($class, $git_dir) = @_;
+       $git_dir =~ tr!/!/!s;
+       $git_dir =~ s!/*\z!!s;
        # may contain {-tmp} field for File::Temp::Dir
        bless { git_dir => $git_dir, alt_st => '', -git_path => {} }, $class
 }
@@ -110,18 +112,22 @@ sub _bidi_pipe {
                }
                return;
        }
-       my ($out_r, $out_w);
-       pipe($out_r, $out_w) or $self->fail("pipe failed: $!");
-       my @cmd = (qw(git), "--git-dir=$self->{git_dir}",
+       pipe(my ($out_r, $out_w)) or $self->fail("pipe failed: $!");
+       my $rdr = { 0 => $out_r };
+       my $gd = $self->{git_dir};
+       if ($gd =~ s!/([^/]+/[^/]+)\z!/!) {
+               $rdr->{-C} = $gd;
+               $gd = $1;
+       }
+       my @cmd = (qw(git), "--git-dir=$gd",
                        qw(-c core.abbrev=40 cat-file), $batch);
-       my $redir = { 0 => $out_r };
        if ($err) {
                my $id = "git.$self->{git_dir}$batch.err";
                my $fh = tmpfile($id) or $self->fail("tmpfile($id): $!");
                $self->{$err} = $fh;
-               $redir->{2} = $fh;
+               $rdr->{2} = $fh;
        }
-       my ($in_r, $p) = popen_rd(\@cmd, undef, $redir);
+       my ($in_r, $p) = popen_rd(\@cmd, undef, $rdr);
        $self->{$pid} = $p;
        $self->{"$pid.owner"} = $$;
        $out_w->autoflush(1);