lmi
[Top][All Lists]
Advanced

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

Re: [lmi] Sharing git repositories


From: Vadim Zeitlin
Subject: Re: [lmi] Sharing git repositories
Date: Tue, 17 Mar 2020 02:28:13 +0100

On Mon, 16 Mar 2020 16:25:06 +0000 Greg Chicares <address@hidden> wrote:

GC> On 2020-03-13 23:26, Vadim Zeitlin wrote:
GC> > On Fri, 13 Mar 2020 22:55:16 +0000 Greg Chicares <address@hidden> wrote:
GC> > 
GC> > GC> On 2020-03-11 00:13, Vadim Zeitlin wrote:
GC> > GC> > On Tue, 10 Mar 2020 23:33:34 +0000 Greg Chicares <address@hidden> 
wrote:
GC> [...]
GC> > GC> I've found it really difficult to make a git repository usable by
GC> > GC> multiple accounts. Please take a look at lmi commit ec1bd048fa,
GC> > GC> which I've just now pushed, and tell me if I'm missing something.
GC> > GC> It just seems that there must be some easier way.
GC> > 
GC> >  Yes, but you seem to have already discovered it and yet discarded it for
GC> > some reason. To me, the following seems easy, even if not very short,
GC> > because each step is perfectly logical:
GC> > 
GC> >   $ git init --bare --shared zlib.git
GC> >   $ chgrp -R audio zlib.git # not necessary if it's your main group
GC> >   $ cd zlib.git
GC> >   $ git remote add origin https://github.com/wxWidgets/zlib.git
GC> >   $ git fetch origin
GC> 
GC> [TL;DR: ...to which we must add:
GC>         $ chmod g+w FETCH_HEAD # necessary (see below); git defect?
GC> ...]

 This was new to me, but I can confirm that even in a shared repository
FETCH_HEAD indeed always has mode of 644, even when using the latest Git.
Looking at the source:

https://github.com/git/git/blob/6c85aac65fb455af85745130ce35ddae4678db84/builtin/fetch.c#L899

the file is created using a simple fopen("a"), and so it uses the default
mode, as determined by umask, and there are no calls to change its mode
later.

 However looking further I see that even before doing this Git calls a
function truncate_fetch_head() which, in turn, calls fopen_for_writing()
which looks like this:

        FILE *fopen_for_writing(const char *path)
        {
                FILE *ret = fopen(path, "w");

                if (!ret && errno == EPERM) {
                        if (!unlink(path))
                                ret = fopen(path, "w");
                        else
                                errno = EPERM;
                }
                return ret;
        }

So it seems that the intention is to overwrite the existing file if we
failed to open it just because we didn't have the permissions to do it.
Except, of course, that fopen() returns EACCESS and not EPERM in our case,
so this code doesn't work. In fact, POSIX doesn't even specify EPERM as one
of the possible errno values for open, see

https://pubs.opengroup.org/onlinepubs/009695399/functions/open.html

while it clearly describes EACCESS. Linux does return EPERM, apparently,
but only in rather exotic circumstances. So I don't really understand why
does Git test for it here and the history doesn't help neither, as it was
added in

https://github.com/git/git/commit/79d7582e32ca84eacf032298c8ae3d26816f48d0

whose commit message doesn't explain the choice of EPERM.

 AFAICS this does look like a defect in Git and I'll try to submit a patch
fixing this there, so that in the future doing "git fetch" as a different
user would still work. I'm not really surprised this hasn't been noticed so
far however, as fetching from a bare repository is a rare (albeit still
perfectly valid) operation.

GC> The instructions that you tailored to my use case above do work,
GC> of course, yet even so there are differences--see commit b65f36fdca.

 I guess this hasn't been committed yet, but I'll look at it later when it
is.

 Regards,
VZ

Attachment: pgp1Sg4U_r3GB.pgp
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]