Monday, July 04, 2011

Git: Repository


Git repository is a storage area that keep the project’s git version control information including logs, commits, version and etc. (a.k.a. repository meta data).  The repository stores in a hidden folder name .git.  There are 2 types of git repositories: bare repository and non-bare repository.

Bare repository

Bare repository is a folder that keep only git’s meta data.  It doesn’t contain project working tree.  In short, it stores all the .git folders and files directly in the folder.

Bare repository always act as a shared repository at runtime.  It has similar role in centralized version control system: the central repository in version control server.  It always act as an origin repository of many non-bare repositories of development task.

Non-bare repository

Non-bare repository or working repository is a storage folder that contain .git and working tree.  It is a repository that used in programmer’s workstation for daily work.  Most non-bare repository are usually clone from bare repository.

Create a new repository

It is common to start a repository as non bare repository:

$ git init ~/myproj
Initialized empty Git repository in /home/usr/myproj/.git/
$ cd ~/myproj
$ ls -a . .. .git $ echo my first project > readme $ git add readme $ git commit -m "My first commit" [master (root-commit) 784a3ce] My first commit Committer: root <root@revision-control.(none)> 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 readme

A new repository has created.  Obviously, this is a non-bare repository.  It contains a .git folder a working tree.  The working tree has a file of name “readme”.

GitFaq states that

A quick rule of thumb is to never push into a repository that has a work tree attached to it, until you know what you are doing.

Thus, we shouldn’t clone the non-bare repository as origin of our working repository in development stage.  We should first make the non-bare repository to bare repository for other to clone;

$ cd ~ 
$ git clone --bare myproj myproj.git
Initialized empty Git repository in /tmp/myproj.git/ 
$ ls -a 
.   .webmin     auth    loggerhead-cache-Hpo6UL  myproj.git 
..  README.txt  config  myproj                   servers

Now, myproj.git is a bare repository of the project.  .git folder isn’t exist in bare repository.  Instead, all contents of .git stores in project folder directly.

What about myproj now?  It doesn’t know myproj.git.  It has no relation with myproj.git now.  If we continue working on myproj.  All commit works have no way to sync (push/pull) with bare repository (myproj.git).  Perform this to make myproj.git as origin of myproj.git:

$ cd ~/myproj
$ git remote add origin ~/myproj.git // for git push $ git config branch.master.remote origin // for git pull $ git config branch.master.merge refs/heads/master // for git pull

The myproj now become a clone of myproj.git.  myproj.git is origin of myproj.  You may push your commits into myproj.git as usual.  It has same working behaviour as other new clone from myproj.git.

Alternatively, you may delete myproj folder and clone from myproj.git:

$ rm –fr ~/myproj 
$ git clone ~/myproj.git ~/myproj

You may also set a default pull behaviour globally if your new project always pull from a origin branch:

$ git config --global branch.master.remote origin
$ git config --global branch.master.merge refs/heads/master

Create a bare repository

Do this If you want to start a bare repository directly:

$ git init -bare myproj.git

A bare repository is created and initialize, you may clone a new working repository from it.

Create a shared repository for team work

To create a git repository that may share for team environment accessed via SSH or other means, use something like:

$ git init --bare --shared=group project.git
Initialized empty shared Git repository in /srv/repos/git/project.git/

List the directory with attributes and notice the group write and setuid bit is on:

$ ls –l
drwxrwsr-x 7 root root 4096 Jul 7 19:27 project.git

Enable write access for developer group:

$ chgrp developer -R project.git
$ ls -l
drwxrwsr-x 7 root developer 4096 Jul 7 19:27 project.git

Share existing repository for team work

To share an existing git repository, try this:

# ls -l
drwxr-xr-x 7 root root 4096 Jul 7 15:17 project.git

Change group of repository:

# chgrp -R developer project.git
# ls -l
drwxr-xr-x 7 root developer 4096 Jul 7 15:17 project.git

Change directories permission:

# find project.git -type d |xargs chmod g+wxs
# ls -l
drwxrwsr-x 7 root developer 4096 Jul 7 15:17 project.git


  1. Stackoverflow: How do you get git to always pull from a specific branch?
  2. GitSubmoduleTutorial
  3. Git Tip of the Week: Setting up a shared repository. url:

No comments: