lmi
[Top][All Lists]
Advanced

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

Re: [lmi] Sharing git repositories


From: Greg Chicares
Subject: Re: [lmi] Sharing git repositories
Date: Mon, 16 Mar 2020 16:25:06 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0

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

[TL;DR: ...to which we must add:
        $ chmod g+w FETCH_HEAD # necessary (see below); git defect?
...]

Yes, I did discover something like that in online research, but was
averse to it because
 - (superficially) different authors present this group of commands
   in ways that seem different, even if they mean the same thing
 - (substantially) there are issues in the details--for example:

https://stackoverflow.com/questions/4108778/what-is-the-difference-between-clone-and-mkdir-cd-init-remote-add-pull

which led me to think that it was a poor idea to try to emulate
git-clone (I no longer think so). One issue discussed there:
| If, for some reason, the remote's HEAD is not master [...]
seems to arise with github.com/wxWidgets/zlib.git (though I'm not
sure whether that's an actual problem).

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

I'm puzzled in particular that after
  git init --bare --shared manual.git
  chgrp -R audio manual.git
  git -C manual.git remote add origin https://github.com/wxWidgets/zlib.git
  git -C manual.git fetch origin
the owning group has write permissions to everything--except
for FETCH_HEAD, which is writable only by its owner, not by
the group. But FETCH_HEAD comes into existence only after the
last command above (git-fetch), i.e., after the commands intended
to configure the repository as group-sharable.

If I run the last command as a different user, then my main
user subsequently can't do git-fetch (here, I've repeated all
the steps using 'eraseme.git' instead of 'manual.git' above):

/tmp/eraseme[0]$sudo --user=pulse git -C eraseme.git fetch origin 2>&1 |less 
/tmp/eraseme[0]$ls -l eraseme.git                             
total 40
-rw-r--r-- 1 pulse audio 8063 Mar 16 12:58 FETCH_HEAD
-rw-rw-r-- 1 greg  audio   23 Mar 16 12:57 HEAD
[...all other files in that directory are owned by "greg:audio"...]
/tmp/eraseme[0]$git -C eraseme.git fetch origin                                 
          
error: cannot open FETCH_HEAD: Permission denied

Adding
  chmod g+ws eraseme.git
to the commands above doesn't prevent that problem. Apparently
it makes no difference at all, because git-init's '--shared'
option already did the same thing--permissions immediately
after git-init are:

  drwxr-xr-x 7 greg greg 4096 Mar 16 14:55 eraseme.git [without --shared]
  drwxrwsr-x 7 greg greg 4096 Mar 16 14:53 eraseme.git [  with  --shared]
       ^^

When FETCH_HEAD is later created, its group ownership is taken
from that of eraseme.git (because the 's' bit is set there),
and the group owner is "audio" (because of the earlier chown),
but its permissions are controlled by umask. Indeed, if I
override umask:

/tmp/eraseme[0]$sudo --user=pulse sh -c umask                                   
      
0022
/tmp/eraseme[1]$sudo --user=pulse sh -c "umask 002 && git -C eraseme.git fetch 
origin" 2>&1 |less
/tmp/eraseme[0]$git -C eraseme.git fetch origin                                 
         
/tmp/eraseme[0]$ls -l eraseme.git 
total 40
-rw-rw-r-- 1 pulse audio 8063 Mar 16 15:06 FETCH_HEAD
-rw-rw-r-- 1 greg  audio   23 Mar 16 15:02 HEAD

then FETCH_HEAD has exactly the desired permissions (the same
as HEAD), and my normal user can then run git-fetch.

This seems surprising to me. I would have expected that, in a
repository created by 'git init --shared', files such as FETCH_HEAD
that are later created by git would have mode 'g+w' automatically.
It does that for these files:

  /tmp/eraseme[0]$ ls -l eraseme.git/refs/remotes/origin/master 
  -rw-rw-r-- 1 pulse audio 41 Mar 16 15:21 
eraseme.git/refs/remotes/origin/master
  /tmp/eraseme[0]$ ls -l eraseme.git/refs/tags/v0.7*
  -rw-rw-r-- 1 pulse audio 41 Mar 16 15:21 eraseme.git/refs/tags/v0.71
  -rw-rw-r-- 1 pulse audio 41 Mar 16 15:21 eraseme.git/refs/tags/v0.79

but not for this one (unless I specifically override umask as above):

  /tmp/eraseme[0]$ ls -l eraseme.git/FETCH_HEAD     
  -rw-r--r-- 1 pulse audio 8063 Mar 16 15:21 eraseme.git/FETCH_HEAD

Isn't that a git defect?

But the alternative I'd proposed also has problems:

/tmp/eraseme[0]$chgrp audio .
/tmp/eraseme[0]$chmod g+s .
/tmp/eraseme[0]$umask=002 && git clone --jobs=32 --bare --config 
core.SharedRepository=group https://github.com/wxWidgets/zlib.git

That seems "leaner" in that it lacks these files:
  refs/remotes/*
  refs/tags/*
but it lacks 'g+w' permissions generally:
  /tmp/eraseme[0]$ls -l zlib.git 
  total 40
  -rw-r--r-- 1 greg audio   19 Mar 16 15:44 HEAD
  drwxr-sr-x 2 greg audio 4096 Mar 16 15:44 branches
  -rw-r--r-- 1 greg audio  155 Mar 16 15:44 config
I had hoped that specifying
  --config core.SharedRepository=group
would have set 'g+w' permissions. Well, it's less bad if I don't
try to combine 'umask 002' with another subcommand (AFAIK, this
is impossible, and "umask 002 && ..." did seem to work above):

/tmp/eraseme[0]$rm -rf zlib.git
/tmp/eraseme[0]$chgrp audio .
/tmp/eraseme[0]$chmod g+s .
/tmp/eraseme[0]$umask 002
/tmp/eraseme[0]$git clone --jobs=32 --bare --config core.SharedRepository=group 
https://github.com/wxWidgets/zlib.git
/tmp/eraseme[0]$umask 022

but even so there's no FETCH_HEAD yet, and therefore:

/tmp/eraseme[0]$sudo --user=pulse git -C zlib.git fetch origin
>From https://github.com/wxWidgets/zlib
 * branch            HEAD       -> FETCH_HEAD
/tmp/eraseme[0]$ls -l zlib.git/*HEAD     
-rw-r--r-- 1 pulse audio 76 Mar 16 15:56 zlib.git/FETCH_HEAD
-rw-rw-r-- 1 greg  audio 19 Mar 16 15:54 zlib.git/HEAD
/tmp/eraseme[0]$git -C zlib.git fetch origin 
error: cannot open FETCH_HEAD: Permission denied

which is the same problem as above.

Conclusions: Your suggestion really is better. For the repository to be
usable by multiple members of the owning group, either
 - FETCH_HEAD's permissions must be fixed up manually, or
 - users should routinely have 'umask 002' (or, say, 007).

In any event, the series of commands that actually works is:

>       $ git init --bare --shared zlib.git
>       $ chgrp -R audio zlib.git # not necessary if it's your main group
>       $ cd zlib.git
>       $ git remote add origin https://github.com/wxWidgets/zlib.git
>       $ git fetch origin
        $ chmod g+w FETCH_HEAD # necessary (see above); git defect?

and
  git clone --bare --config core.SharedRepository=group
does not set ownership (of files other than FETCH_HEAD) the same way that
  git init --bare --shared zlib.git
does, so
  git clone --bare --config core.SharedRepository=group
is an anti-idiom.


reply via email to

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