Search code examples
gitgit-submodulesgit-subtreegit-slavegit-subrepo

git submodules , gitslave, git subtree or a simpler solution


We have a git repository with N folders.

Repo
|-Folder1
|-Folder2
|- ...
|-FolderN

With different collaborators we would like to share different folders. Each collaborator should have access only to his allowed subset of folders. What is the "good" way to achieve this using git?


An answer was to use git submodules. But after I read this article: https://codingkilledthecat.wordpress.com/2012/04/28/why-your-company-shouldnt-use-git-submodules/ I understood that you need to have a good mastery of git (which is not the case of our collaborators) in order to not have problems when using git submodules.

I read about some possible alternatives like gitslave, and git subtree. gitslave seemed to be a good solution but still a complex solution in my opinion.

Here is my simple solution and I would like to know if it can have some very bad drawbacks :

-Having a simple repository for each Folder and a repository for Repo. Then add all the files in Folder1, ..., FolderN in the main Repo.

-globalpush script:

function globalpush(){
REPOS="$HOME/Repo/
       $HOME/Repo/Folder1
       $HOME/Repo/Folder2
       $HOME/Repo/Folder3
       # ...
       $HOME/Repo/FolderN"   

#do not show untracked files
git config status.showuntrackedfiles no

read -p "Commit description: " description

for repo in ${REPOS}
do
    # if the repo folder exists
    if [ -d $repo ]
    then
        # Go inside the repo
        cd $repo
        echo "-----PUSHING REPO : "$repo"-----"

        #add all modified all deleted TRACKED files
        git add -u .

        git commit --allow-empty -m "$description"
        git push                
    else
        echo "-----COULD NOT FIND : "$repo"-----"
    fi
done

#show untracked files again
git config status.showuntrackedfiles normal
}

-globalpull script:

function globalpull(){
REPOS="$HOME/Repo/
       $HOME/Repo/Folder1
       $HOME/Repo/Folder2
       $HOME/Repo/Folder3
       # ...
       $HOME/Repo/FolderN"           

for repo in ${REPOS}
do
    # if the repo folder exists
    if [ -d $repo ]
    then
        # Go inside the repo
        cd $repo
        # pull the modifs.
        echo "-----PULLING REPO : "$repo"-----"
        git pull                        
    else
        echo "-----COULD NOT FIND : "$repo"-----"
    fi
done
}

The advantages of this solution are:

1 - Simple solution that everyone can understand.

2 - Possibility to give the access rights for each Folder independently.

3 - For the main developers (who have access to Repo) the repository Repo is self-contained, and contains all the history (in case something goes wrong with the repositories of Folder1, ..., FolderN).

4 - when a main developer makes a commit with a given description, a commit with the same description will be created for all the Folders repositories, even those without a modification (--allow-empty), which of course isn't perfect but helps tracking versions that are submitted by main developers.

EDIT :

There seems to be a new command I was not aware of git subrepo ...


Solution

  • git-subtree was the winning solution and in fact it does what I was doing with my scripts and much more, in a better "git-native" way.

    Here is a link to the tutorial that we've followed to setup our environment.

    https://hpc.uni.lu/blog/2014/understanding-git-subtree/