From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.2 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, T_SCC_BODY_TEXT_LINE shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id BEAF61F724 for ; Tue, 28 Nov 2023 14:56:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=80x24.org; s=selector1; t=1701183389; bh=7IFjWzGb7u/Uv4jGStvWnNUWRRu76qzZ0oi7flz45us=; h=From:To:Subject:Date:In-Reply-To:References:From; b=JbWFVbRSKM6EZOvPB1o/sdGzqAhl9utE+vH1GlqTwprheT2vzd6ohqCEPNqJXVRzF YAuNcujIlvIHBeS1foaIK0bhuyZE6sgXIE42PXAPxs5zYV3zriplSj0XvrpTHF1ZcL /HdR6pjlC2Qe5JXnYxmNDAJq7GgK2gcu6OjZFQmQ= From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 12/14] admin: resolve_git_dir respects symlinks Date: Tue, 28 Nov 2023 14:56:25 +0000 Message-ID: <20231128145628.1455176-13-e@80x24.org> In-Reply-To: <20231128145628.1455176-1-e@80x24.org> References: <20231128145628.1455176-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: Absolute pathnames of git coderepos are stored in the cindex, but we should favor paths relative to $ENV{PWD} since it respects symlinks in the heirarchy. Respecting symlinks makes it easier to migrate cindex to new storage as old storage wears out and to relocate the storage device onto another machine. --- lib/PublicInbox/Admin.pm | 25 +++++++++++++++++++++---- 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; } diff --git a/t/admin.t b/t/admin.t index 20e3deb7..586938d0 100644 --- a/t/admin.t +++ b/t/admin.t @@ -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');