23

The Issue: when multiple users have access to the same working directory, permissions issues can occur in the meta-data if any git operations are performed.

DISCLAIMER: Before you chastise me - I realize sharing a working dir is counter to what Git stands for, and I am not talking about doing anything other than read-only operations in this shared directory - we do all our work in our own local repositories.

I'm open to suggestions as to another way to do what we are trying to do, as our approach is certainly not best practice, but I'm not sure that conversation that would be useful for others to listen to. So for now let me provide some details on why we are doing this:

We have several build-masters on our team. We deploy to Linux servers, and we do our builds there, with build scripts that pull directly from Git. We are not able to use CI (such as Jenkins/cruisecontrol) at this time, so we have a repository that we checkout and do our QA builds from.

There are some git operations that we perform as part of the script. This includes some tagging of commits (stuff gets tagged as QA-current, QA-previous, etc...). So I guess we aren't actually read-only entirely. Due to the nature of the build script, we run it sudo'ed as a common user (let's call that user DevAdmin). I realize this might be a bad practice, and is perhaps the source of the pain, since it forces us to use a shared repo checkout.

This would all be fine, if we were always sudo'ed when in that working dir. The issue is that on occasion, one of us will do a git pull or something similar by accident, without being sudo'ed as DevAdmin. So most of the files in .git are owned by DevAdmin (who performed the initial clone), but whenever we do this, we end up with dir's in .git/objects that contain files owned by a specific user. And these are created as group-unwritable. I've also noticed ORIG_HEAD with wrong ownership, for example. So when we try to do something as DevAdmin, we get issues.

Is there anything that we can do to fix this issue? Right now, we have to recognize that it has happened, and then get a server admin to chown .git back to DevAdmin. Or have the user delete the meta-files in question, or at least chmod them to group-writable. This all seems very bad.

I've considered a couple of options that don't involve changing our build and maintenance processes dramatically:

If we removed group-write access on .git and restricted it to DevAdmin, would that prevent this from happening again? This seems the most straightforward option.

Or is there a way to make everything in .git group-writable, even when it's newly created? This seems like asking from trouble.

Is there something else obvious I'm missing? I realize that the best thing would probably be to change our process so that users could work in their own repo's, but in a business setting, the repos can get very large (jars aren't separated out yet, lots of binary files, etc...), and we can't have multi-GB repos for everyone's account. Additionally, our system administrators would have a lot of work ahead of them changing their processes to allow for it.

Any thoughts are appreciated.

kghastie
  • 739
  • 1
  • 7
  • 14

3 Answers3

35

There are a number of ways to address this problem. Personally, I'd recommend the following in your existing repository:

# Create a group named "gitshare" that will share the repository.
sudo groupadd gitshare

# Add yourself and as many others as you want to the group.
sudo adduser "$LOGNAME" gitshare

# Everything else needs to run from the top level of your Git repository.
cd /path/to/repository

# Add group permissions for *new* modifications to repository.
git init --shared=group

# Fix permissions for existing repository objects.
chown -R :gitshare "$PWD"
chmod -R g+swX "$PWD" 

Obviously, you need to make sure that the users have directory traversal permissions all the way to your repository (e.g. user-private directories may cause problems), and that all team members who need access belong to the repository's shared group. After this initial setup, though, it should "just work."

Community
  • 1
  • 1
Todd A. Jacobs
  • 81,402
  • 15
  • 141
  • 199
  • Great - we are all already part of the DevAdmins group, so I think all I'd need to do is the init and the one-time permissions fix. I looked into the --shared flag, but most mentions of it were in regards to sharing a bare repo, and I thought it related more to sharing a remote repo, which didn't make sense. But of course - this is just the local repo that is shared. Thanks for hammering home an obvious point. Guess I haven't been successful yet in fully git-i-fying my thinking... – kghastie Jun 26 '12 at 13:16
  • Your adduser command didn't work for me (usage error) instead I did `sudo usermod -a -G gitshare "$LOGNAME"` – Rodney Feb 20 '18 at 05:14
2

I just faced this issue and took me hours to find the solution when it was so simple. I tried almost everything I see on the other link provided by CodeGnome.

I'm using Centos 6.x and the solution was to change the umask on users... this require we do it with each account... We are only 2 working on the same directory. Not that much of a pain.

The solution that worked for me is this one, without having to change the server's configuration: http://www.avajava.com/tutorials/lessons/how-do-i-set-the-default-file-and-directory-permissions.html

If the .bashrc filoe do not exists in /home/user directory, like this was in my case, you only need to copy from the skeleton the file in /ect/skel and then you copy it your home (users) directory after adding at the end of the file:

umask 002

This gives the user a chmod 775 on the new folders created by others in the group. Of course, once this project will be completed, not anymore in a testing environment, we will set it back to chmod 755 (umask 022) by default. This not only give Git the permission to overwrite but also to write files uploaded on sFTP without having the permission denied issue. .

MyraGe
  • 53
  • 1
  • 6
  • This worked great for me, thanks. (I actually wrapped the git push command with umask 002 before and umask after.) – Oh Come On Jan 30 '18 at 15:37
1

I made it here 9 years later when searching on Google, and I think I came up with a novel solution for my particular use-case.


Solution: On the remote repo, we created a hook that would grant write and execute permissions to the group. The hook is in the remote repo's directory, under the hooks directory, and named post-receive (no file extension; we had to manually create the file and with execute permissions). We created it as a bash script that looked something like:

#!/bin/sh
chmod -R g+rwx /path/to/remote/repo

All users involved are part of the same group, and the git hook is run as the user who did the push. So that user basically changes the files they have access to, allowing anybody else in the group to have access.


Situation: At work, we had a folder with decades worth of programs that regularly get updated and tweaked. We want version control, so we set up a remote (on the same machine though) and we git inited the folder in question and pointed it at the remote. The more adventurous of us wanted to clone the repo to our laptops and work on the codebase there, and then push changes, but we wanted the less adventurous to not have to fetch/pull. The repo is on the same machine as the original codebase, so we made a git hook that would automatically propagate changes.

The server owners are appropriately strict about permissions, resulting in a umask policy where our (shared) group doesn't automatically get write permissions. We also aren't sudoers so we can't force it to work (so-to-speak).

"Gotchas":

  • If you are already in the situation where you can't push due to file permissions, have each of the users grant permissions (chmod -R g+rwx /path/to/remote/repo). They'll get errors for the files they don't have access to, but that is fine. Once everybody has done that, you should be good to go :)
  • This isn't pertinent to the OP, but in our situation, we had the hook fetch+pull within the local clone, followed by updating the permissions on the clone's .git directory contents as well. We forgot that last part originally :|

Disclaimer: I am not a pro with any of this-- security, linux, or git. I knew enough to get it to work within the confines and limitations I have, but I'm sure there are better ways.


Hopefully this helps somebody else, and sorry if I got any of the terminology wrong!

Zeda
  • 382
  • 4
  • 13