Sharing git repos between two system users
I needed a way for two developers to access a git repository on a Linux machine. Each developer has their own dedicated system user and logins require 2FA. Here’s how I got this going.
Our environments at work require 2FA for our user accounts. This means that a simple approach of allowing each user to SSH to each other won’t work since they can’t access each other’s phones.
Each user does belong to the same group (i.e. webdevs
). This means if we can
ensure that files and directories in the repository all have g+rw
permissions at least, they can both access them.
Searching for a solution I came across git config
core.sharedRepository
which seems like it was designed exactly for this
use case. In short, you can run git config core.sharedRepository MODE
to
tell git to set file permissions on all new files created during git pull.
It didn’t seem to impact newly created files. So, special group bit to
the rescue. On Linux machines, we can assign this with something like chmod
g+s path
.
Finally, we need a way to assign g+rw
permissions on the repo clone itself.
With the background out of the way, here’s what I did:
First, we set a temporary umask (my default is 0022) that creates files with group writable permissions:
umask 0002
Then clone the repository using the core.sharedRepository
setting mentioned
above:
git clone -c core.sharedRepository=0664 git@github.com:foo/bar.git /var/www/example.com
Before you forget, remember to set your umask back. If you don’t know what it is, just exit SSH and sign in again. If you forget, any files you create in your SSH session are probably going to have unexpected permissions.
Assign the group special bit to the repository root directory:
chmod g+s /var/www/example.com
Fix ownership of the repository:
sudo chgrp -R webdevs /var/www/example.com
Each developer then needs to allow git to access our clone which has non-standard permissions:
git config --global --add safe.directory /var/www/example.com
Now, each developer can test it by trying to create files and pushing/pulling from GitHub.
cd /var/www/example.com
git checkout -b "test-$USER"
echo test > "test-$USER"
git add "test-$USER"
git commit -m "Testing from $USER"
git push -u origin "test-$USER"
As files get pushed and pulled the owner will change up a bit but the group
will remain the same. Since we’ve set the group read/write special bit on the
repository root, both devs can write to all files. Git will ensure files get
664 permissions by default. And lastly, Git doesn’t store user or group
permissions, only execute permissions, and config.sharedRepository
is
smart enough to not clobber your executable files with 664 permissions.