Can't use bare repositories with Git.pm

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux