Git: Sharing a single git controlled folder among a group under Linux

With the modern mantra of “everything is code”, operations and network teams must come to terms with how they want to work with source control in a team environment.

Imagine a repository that contains configuration templates and scripts for maintaining an application or appliance.  For a multi-member operations team who shares the responsibility for this resource, does each member of the team checkout the trunk or branch under their home folder, OR does it make more sense for all members to simply work out of the same folder?

This is ultimately up to the company policy and team preference, but I would argue that operations teams tend to be pragmatic and the simpler you can make life while still keeping the benefits of version control and individual auditing the better.

In this article I will show how to use the git ‘core.sharedRepository’ setting in conjunction with setgid on the folders to share a single folder among users of the same group.

Prerequisites

This article is written assuming a remote git repository will be cloned to a Linux host.   That Linux host has a group called ‘mygroup’, and users ‘alice’ and ‘bob’ are both members of that group.

You can create this group and users manually, or use the script from the github project for this article.

Overview

The repository will be cloned into the folder ‘/home/shared/test-group-repo’, and both Alice and Bob will be able to create, update, and commit directly from that folder.  They will each have full permissions to all files, and git logs will reflect the individual who made the change.

Configuration

First, we will create the base directory for this work.  Then clone a branch of my project for this article (or better yet fork it so you can test the commits yourself).

mkdir -p /home/shared
cd /home/shared
git clone -b test1 https://github.com/fabianlee/test-group-repo.git

Then we will set the group id of the folders recursively so that any files created or modified in this directory structure will be owned by the ‘mygroup’ group.

# look at original owner/group for files, directories, and .git
find -type d -not -path "*.git/*" | xargs ls -l

# changes group ownership to mygroup throughout entire tree
sudo chgrp -R mygroup test-group-repo

# sticky bit on root folder ('s' in group execute position)
sudo chmod g+s test-group-repo
ls -ld test-group-repo
drwxrwsr-x 5 fabian mygroup 4096 Dec  1 18:02 test-group-repo

# sticky bit on all folders
find test-group-repo -type d -exec sudo chmod g+rwxs {} \;

# validate 
find -type d -not -path "*.git/*" | xargs ls -l

Testing

Finally, we need to validate that creation, modification, and commits maintain this group ownership and that commits are attributed to the correct user.

I created two github test accounts for the local users alice and bob, ‘alice-flee999-test-group-repo’ and ‘bob-flee999-test-group-repo’.

Alice

First configure the git client logged in as the user ‘alice’.

# switch to user alice (either via sudo or ssh)
sudo su alice

# set git configuration for alice
git config --global core.sharedRepository group
git config --global user.email alice-flee999-test-group-repo
git config --global user.name "alice"
git config --global push.default simple
git config --global credential.helper 'cache --timeout=3600'

Then go into the shared repository folder and make a change to an existing file as well as create a new file.

cd /home/shared/test-group-repo

echo "alice changed" >> common.txt
echo "alice changed1" >> firstconfig/one.txt

echo "alice created1" >> firstconfig/onealice.txt
git add firstconfig/onealice.txt

git status
git commit -a -m "alice changes"
git push

Verify Repository changes

Pulling up the test-group-repo on the ‘test1’ branch I can now see that the user ‘alice’ made two file modifications and one creation as expected.

Verify local permissions

Running the following command, the permissions of the directory structure are displayed.

find -type d -not -path "*.git/*" | xargs ls -l

The file alice created ‘firstconfig/onealice.txt’ is owned by her and ‘mygroup’ with read/write permission for the group.  That means that Bob (who is also in her group) also has full control.

There may also be new files in the ‘.git’ book keeping directory (e.g. COMMIT_MSG, index, etc) owned by alice and ‘mygroup’ which is what we expected and wanted.

The problem would be if any of these new files did not have group ownership or permissions.

Bob

We’ve shown that the Alice can work with these files, but the real test will be to show that Bob can also work in this same folder.

Configure the git client logged in as the user ‘bob’.

# switch to user alice (either via sudo or ssh)
sudo su bob

# set git configuration for bob
git config --global core.sharedRepository group
git config --global user.email bob-flee999-test-group-repo
git config --global user.name "bob"
git config --global push.default simple
git config --global credential.helper 'cache --timeout=3600'

Then go into the shared repository folder and make a change to an existing file as well as create a new file.

cd /home/shared/test-group-repo

echo "bob changed" >> common.txt
echo "bob changed1" >> secondconfig/two.txt

echo "bob created1" >> secondconfig/twobob.txt
git add secondconfig/twobob.txt

git status
git commit -a -m "bob changes"
git push

Verify Repository changes

Pulling up the test-group-repo on the ‘test1’ branch I can now see that the user ‘bob’ made two file modifications and one creation as expected.

Verify local permissions

Running the following command, the permissions of the directory structure are displayed.

find -type d -not -path "*.git/*" | xargs ls -l

The file bob  created ‘secondconfig/twobob.txt’ is owned by him and ‘mygroup’ with read/write permission for the group.  And the ‘index’ file in the ‘.git’ book keeping directory may also be owned by bob and mygroup which is what we expected and wanted.

git log audit

Looking the git log of ‘common.txt’, modified by both alice and bob, there is a record of both users making a modification and the exact times.

$ git log common.txt
commit 90c8d0f45a941f6f472c537e4f3008a01adc0348
Author: bob <bob-flee999-test-group-repo>
Date:   Sat Dec 1 18:58:37 2018 -0500

    bob changes

commit 92718b576069af6a1b748b1cf126c38f825de1da
Author: alice <alice-flee999-test-group-repo>
Date:   Sat Dec 1 18:34:59 2018 -0500

    alice changes

commit 1f192b2da33f1ee3273f79d81697dc033aac1047
Author: flee999 <flee999@hotmail.com>
Date:   Sat Dec 1 16:59:09 2018 -0500

    testing files

Summary

Moving to a single shared folder may not make sense for every project or team, but it is an alternative that can be considered when the benefits of source control need to be applied to what would otherwise be a shared team folder that is manually managed.

 

REFERENCES

https://stackoverflow.com/questions/4832346/how-to-use-group-file-permissions-correctly-on-a-git-repository

https://stackoverflow.com/questions/15076348/how-to-keep-git-from-changing-file-ownership

https://ryansechrest.com/2013/08/managing-file-and-folder-permissions-when-deploying-with-git/

http://www.toptip.ca/2010/03/linux-setgid-on-directory.html