git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Can't use bare repositories with Git.pm

From
RRodrigo <rodrigolive@gmail.com>
Date
Sep 12, 2024, 16:32 UTC
Message-ID
<CAGUZU_JZd_+8y19=kGif6u1+4n_+iOcVWV4p-kC0Uo=8Ev=aBA@mail.gmail.com>

We're having an issue migrating from 2.31.1 to 2.46.0. The following Perl code does not work in 2.46.0 as it did in 2.31.1 (tested linux and darwin, did not check Windows):

    # test.pl
    use Git;
    my $repo = Git->repository( Directory => '/repo/bare.git' );
    my ($fh, $ctx) = $repo->command_output_pipe('rev-list', "2acf3456");
    print do { local $/; <$fh> };
Run:
   $ cd /home/rodrigo
   $ perl test.pl
Fails with the error:
    fatal: not a git repository: '/home/rodrigo'

If the repository it points to is a *bare repository* outside of the current working directory, it only works if the directory is a child directory to the bare (/repo/bare.git/info). The code above does work for non-bare repos, and also works if we set `Repository => "/repo/bare.git"` instead of `Directory => ...`, but the Git.pm documentation states `Directory => ...` should work for both bare and non-bare alike, like it did in 2.31.1 (and other versions).

Bug hunting through the Git.pm code and skimming through the Git SCM repo, there's a significant change (commit 20da61f25) that makes the recent Git.pm rely on:

     git rev-parse --is-bare-repository --git-dir

for locating the correct (maybe a parent) repo directory. The change was understandably done for security (and other many) reasons. It started using --is-bare-repository to detect if it's a bare repository we're dealing with, instead of relying on the old Git.pm redundant code for bare repo detection, which was a sound decision. But some crucial code was taken out.

Now if the directory path we're passing to `Directory => ...` is a bare repo this new code will fail because git rev-parse --git-dir will return a dot `.` (internally Git.pm will chdir() to the directory before running git rev-parse, hence the result). The issue is that the dot is now is being taken as is by Git.pm as the intended directory, tricking it to think my cwd /home/rodrigo is the bare repository, leading finally to the fatal error.

This could even become a security issue if the Perl program runs from another working dir which happens to be a sensitive repo. Git.pm commands would take action on the wrong repo. This hypothetical Perl program, if run as, ie., a server program, could reveal / change sensitive information from/on a server.

SOLUTION: I propose using "--absolute-git-dir" instead of "--git-dir":
    git rev-parse --is-bare-repository --absolute-git-dir

Which will replace the `.` rev-parse response with a full path resolved by git itself (and not Perl). This means the change to the Perl code is minimal. I don't know if this will resolve all possible cases, but it does fix our issue.

Here's a diff on my proposal -- sorry, noob in this neck of the woods, didn't know if this is the correct way to contribute, but the change is tiny and better if parsed by seasoned eyes anyway:

diff --git a/perl/Git.pm b/perl/Git.pm
index aebfe0c..63d0f92 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -187,7 +187,7 @@ sub repository {
                try {
                  # Note that "--is-bare-repository" must come first, as
                  # --git-dir output could contain newlines.
-                 $out = $search->command([qw(rev-parse
--is-bare-repository --git-dir)],
+                 $out = $search->command([qw(rev-parse
--is-bare-repository --absolute-git-dir)],
                                          STDERR => 0);
                } catch Git::Error::Command with {
                        throw Error::Simple("fatal: not a git
repository: $opts{Directory}");


thanks and best regards,
Rod
gihub.com/rodrigolive
Next: Jeff King
Message 1 of 7 in “Can't use bare repositories with Git.pm”
  1. RodrigoSep 12, 2024
  2. 0/2 fix bare repositories with Git.pmJeff King, Sep 12, 2024
  3. 1/2 Git.pm: fix bare repository search with Directory optionJeff King, Sep 12, 2024
  4. Patrick SteinhardtSep 13, 2024
  5. 2/2 Git.pm: use "rev-parse --absolute-git-dir" rather than perl codeJeff King, Sep 12, 2024
  6. Patrick SteinhardtSep 13, 2024
  7. Junio C HamanoSep 13, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.