Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making git push respect permissions?

We use a git repo that is hosted at a remote location, and is shared. We want the repo to be user & group readable & writeable, but not have any permissions for other. The remote repo is owned by a different user (say rUser). I have set core.sharedRepository to 0660 in my local repo, as well as the remote repo. Also, my umask is 0027. So, whenever I create a new file, it has no permissions for other.

In spite of all this, for some reason whenever I push a change to the remote repo, it creates some new objects in the repo.git/objects/ directory with permissions -r--r--r--. What's even weirder is that it makes me (instead of the remote user) the owner of the directories/files. Any idea what's going on?

I tried finding an answer by going over several seemingly related questions on stackoverflow, but couldn't find anything.

like image 543
user10 Avatar asked Mar 10 '11 19:03

user10


People also ask

Does git care about file permissions?

1 Answer. Show activity on this post. When Git checks out files, it by default uses the umask of the file on the system, setting the executable bit if it's a directory or it's marked as an executable file. That's because Git removes and re-creates the file, so it doesn't preserve the permissions of the existing file.

Why is git push being rejected?

A commit gets rejected and causes a failed to push some refs to error because the remote branch contains code that you do not have locally. What this means is that your local git repository is not compatible with the remote origin. Based on the above, your local machine is missing commits C and D.


1 Answers

Note: I am assuming that you are using an SSH-based access mechanism with each user logging into the server as their own user (i.e. you do not have multiple users login to a single account to access the repository). If this assumption is not true, then the following answer may not be wholly useful.


The core.sharedrepository setting of your personal repository and the umask you use to access it are irrelevant to the ownership and permissions used on a remote repository.

Setting core.sharedrepository to 0660 in the remote repository is the right way to get what you say you want. The umask of the accessing user on the remote side is also irrelevant because Git will override the mask when it sees a 0xxx value for core.sharedrepository. You do need to make sure all the files and directories are group-owned by the your common group and that the permissions are correct (2770 for all directories (or just 770 for BSD-ish systems); 440 for files under objects/?? and /objects/pack/; 660 for other files).

It is normal that a new file is user-owned by the user that created it. On non-BSD systems you need the setgid bit (the 2000 bit) on directories to make new entries inherit the group-owner of its parent directory. The user-owner is rarely inherited (FreeBSD can be configured to do it with the setuid bit, but this is not used in normal configurations). Thus, all the files and directories should have the same, common, group-owner, but each write to the repository (e.g. push) will leave some files and/or directories that are user-owned by the writing user1 (i.e. it is not required that any one user (your rUser?) be the user-owner of all the files and directories; any user that needs access to the repository should be a member of common group).

1 Each user will obviously user-own any files/directories they create, but they will also user-own most files that they modify because Git uses “atomic rewrites” (it writes the new content to a new, separate file in the same directory, and then renames it atop the original file).

Maybe there is a bug in the way Git is overriding the umask for new files. Exactly which files are getting permissions that are too wide? What version of Git are you on the remote end to access on the repository? What OS are you running on the remote end?

I was unable to reproduce this problem with Git 1.7.4.1 with two users and a common group on my Unixy machine.

You might try simplifying the scenario a bit. Try pushing to the remote repository directly from the server itself (i.e. make a local clone and push to a throw-away branch). Doing local-only access makes it easier to check your assumptions (umask; uids; gids; user-, and group-ownership, and permissions of files and directories before and after pushing) than when you have a transport of some kind in the middle (either Git’s own SSH-based transports, or a network filesystem that might not map ids and permissions with full fidelity).

like image 192
Chris Johnsen Avatar answered Sep 29 '22 07:09

Chris Johnsen