diff options
-rw-r--r-- | lib/PublicInbox/Admin.pm | 25 | ||||
-rw-r--r-- | t/admin.t | 12 |
2 files changed, 33 insertions, 4 deletions
diff --git a/lib/PublicInbox/Admin.pm b/lib/PublicInbox/Admin.pm index 893f4a1b..cc9d2171 100644 --- a/lib/PublicInbox/Admin.pm +++ b/lib/PublicInbox/Admin.pm @@ -63,15 +63,32 @@ sub resolve_inboxdir { $dir; } +sub valid_pwd { + my $pwd = $ENV{PWD} // return; + my @st_pwd = stat $pwd or return; + my @st_cwd = stat '.' or die "stat(.): $!"; + "@st_pwd[1,0]" eq "@st_cwd[1,0]" ? $pwd : undef; +} + sub resolve_git_dir { - my ($cd) = @_; + my ($cd) = @_; # cd may be `undef' for cwd # try v1 bare git dirs + my $pwd = valid_pwd(); + my $env; + defined($pwd) && substr($cd // '/', 0, 1) ne '/' and + $env->{PWD} = "$pwd/$cd"; my $cmd = [ qw(git rev-parse --git-dir) ]; - my $dir = run_qx($cmd, undef, {-C => $cd}); + my $dir = run_qx($cmd, $env, { -C => $cd }); die "error in @$cmd (cwd:${\($cd // '.')}): $?\n" if $?; chomp $dir; - # --absolute-git-dir requires git v2.13.0+ - $dir = rel2abs_collapsed($dir, $cd) if $dir !~ m!\A/!; + # --absolute-git-dir requires git v2.13.0+, and we want to + # respect symlinks when $ENV{PWD} if $ENV{PWD} ne abs_path('.') + # since we store absolute GIT_DIR paths in cindex. + if (substr($dir, 0, 1) ne '/') { + substr($cd // '/', 0, 1) eq '/' or + $cd = File::Spec->rel2abs($cd, $pwd); + $dir = rel2abs_collapsed($dir, $cd); + } $dir; } @@ -6,6 +6,7 @@ use v5.10.1; use PublicInbox::TestCommon; use PublicInbox::Import; use_ok 'PublicInbox::Admin'; +use autodie; my $v1 = create_inbox 'v1', -no_gc => 1, sub {}; my ($tmpdir, $for_destroy) = tmpdir(); my $git_dir = $v1->{inboxdir}; @@ -23,6 +24,17 @@ SKIP: { }; *resolve_inboxdir = \&PublicInbox::Admin::resolve_inboxdir; +*resolve_git_dir = \&PublicInbox::Admin::resolve_git_dir; + +{ + symlink $git_dir, my $sym = "$tmpdir/v1-symlink.git"; + for my $d ('') { # TODO: should work inside $sym/objects + local $ENV{PWD} = $sym.$d; + chdir $sym.$d; + is resolve_git_dir('.'), $sym, + "symlink preserved from {SYMLINKDIR}.git$d"; + } +} # v1 is(resolve_inboxdir($git_dir), $git_dir, 'top-level GIT_DIR resolved'); |