$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;
}
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};
};
*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');