Setting up "bare" "shared" GIT repository

This is all about setting up GIT repository to behave in such a way that all developers can push their changes and can pull others changes from central shared repository, ultimately they are going to clone the repository into their local location and each user's "working copy" will itself be a fully-fledged Git repository but to make the code changes centralized they have to push and pull to the central repository that can be on a remote server. e.g. http://source.example.com , we will call this server as source.

Now lets get to some basics of GIT repository. The purpose of Git is to manage a project, or a set of files, as they change over time. Git stores this information in a data structure called a repository. when ever we initiate a GIT repository it actually creates .git directory which is actually stored in same project directory as subdirectory, which actually holds the code's versioning information, its like a growing tree structure and holds each and every commit made to the repository

A git repository contains, among other things, the following:

  • A set of commit objects.
  • A set of references to commit objects, called heads.

A Simple Repository

To create a repository, create a directory for the project if it doesn’t exist, enter it, and run the command git init. The directory does not need to be empty.

$ mkdir [project]
$ cd [project]
$ git init

This will create a .git directory in the [project] directory. All other files and directory in [project]directory other than .git directory are called the working code copy.

A Bare/Shared Repository

To create a bare-shared repository, create a directory for the bare project repository if it doesn’t exist, enter it, and run the command git init --bare --shared.

$ mkdir [project-repo]
$ cd [project-repo]
$ git init --bare --shared

It doesn't matter what user you run above command as. The --shared option sets the permissions on everything in the repository to group-writable. For this purpose make sure all your users who are going to play with this repository belongs to or are member of dev group and have umask 0022. To comprehensively elaborate the following example lets create two users and assign them to a group that have privileges to make changes to the repository.

$ groupadd dev

$ useradd -g dev user1
$ passwd user1 

$ useradd -g dev user2
$ passwd user2

Because this will only create a .git directory in the [project-repo] directory. So there will be no working code copy, it will be considered as bare repository that will hold among code changes, commits and head information. Above example will only create a single repository, and if you provide a name for your repository then you can have as many repositories initiated. In below example, I am going to create two repositories one for my project which is on Drupal 6 called project6 and other for my project that is on Drupal 7 lets call it project7

$ mkdir [project-repo]
$ cd [project-repo]

$ git init --bare --shared project6.git
Initialized empty shared Git repository in /project-repo/project6.git/
$ chgrp -R dev project6.git
$ chmod -R g+swx project6.git

$ git init --bare --shared project7.git
Initialized empty shared Git repository in /project-repo/project7.git/
$ chgrp -R dev project7.git
$ chmod -R g+swx project7.git

As I mentioned above that our server is named source.example.com, and the new repository lives in the /project-repo/project6.git and /project-repo/project7.git directory. To anyone with ssh access to the server, the repository is now available at ssh://source.example.org/project-repo/project6.git and ssh://source.example.org/project-repo/project7.git

As this was setup as bare repository so each user has to clone these repositories to make local working copies and repositories. Just run the following commands on your local workstations with git installed

$ git clone ssh://[username]@source.example.com:/project-repo/project6.git
$ git clone ssh://[username]@source.example.com:/project-repo/project7.git

Please refer to the git config manual, look for core.sharedRepository and core.bare config options and their respective decriptions, this will help you understand why the umask and group permissions are required to avoid several conflicts.

$ git config --help
$ git config --list