Bare and Non Bare Repositories , .git directory and working tree

Understand git clone , svn checkout Vs git cloneThese days I am busy in learning GIT distributed versioning system as our project is going to be sit on it, so I am reading a lot and trying to understand it so that I can take full advantage of it in my project.In my previous post we have seen the working of git clone command and how it is different from svn checkout.
In this post we are going to see some differences between bare and non bare repositories, which one to use when.
A normal GIT Repository basically made up of 2 components –

1. Working directory : In simple terms it is the place where all checked out files reside and file available in this location can be added to git repository by

git add FILE_NAME

.2. .git Directory : In simple terms this directory contains all the administrative related files and data that are required by GIT to support all the commands like git commit, git status , git pull, git push. This directory is always present in the root of your project directory.

So , let’s start looking into the bare and non bare repositories.
Bare Repositories : Bare repository is your same normal repository except the difference that it don’t have any working directory in it and contents of .git directory are present directly inside it. Now you might be thinking that why it don’t have a working directory , what is the use of it if it don’t have working directory , here is the answer and we will see it with the help of example.
Let’s assume you want to create a repository for you and for your team on some server or on your local system. You executed below mentioned commands.

$ mkdir my_first_git_repo
cd my_first_git_repo
git init

Bare and Non Bare RepositoriesNow suppose you created some file and now you want to add it into your repository.

git add my_first_file
git commit –m “My First Commit” my_first_file

Bare and Non Bare RepositoriesNow when you fire git status command you will see the message something like this

git status

Bare and Non Bare RepositoriesSo, till now everything is going as expected , as we are able to successfully create and add a file to our repository. Now somebody cloned from our repository and wants to add a new file to it and want to push back into the repository. Let’s see the flow.Bare and Non Bare Repositories

From the flow it is very clear that I cloned from a non-bare repository , added a new file to it , did the commit and finally pushed it. But while during the push you can see that I got the error that I can’t push to a non-bare repository.

Bare and Non Bare RepositoriesBare and Non Bare RepositoriesNow , what the heck why I can’t push to the non-bare repository , so here is the explanation.

Non-bare repositories : A non-bare repository contains both the working directory and .git directory as explained above.
So, when you do a push from your cloned repository to the remote repository (on some server or in your local) , GIT will check its magic directory that is nothing but .git directory , and then magic directory will tell it you should have 2 files with name my_first_file.txt and I_want_to_add_this_file.txt but when it looks into the working directory it will find only the 1 file , as it was not allowed to push the file in non-bare repository.

Now why push was avoided , lets understand it with an example.
As you have created your central repository as non bare repository and multiple developers are working on this repository and pushing their changes (won’t be allowed but assume). So, now suppose you executed

git status

at your remote repository , you will see something like this as expected.
Bare and Non Bare Repositories
Now in the meantime some other developer pushed his changes into the repository and then you executed the same command git status again , this time you will see a different state as the working directory is changed , but ideally you should not see those changes as those are not made by you and are not from your local working directory , so here is the conflict. That’s why a non bare repository don’t allow you to push in it.
If you want to push in it you have to make your remote repository as bare,like this

 git --bare init

as bare repository don’t have any working directory so when you push it will only update the contents of magic directory.
Now in the last if you want to transfer changes from one non-bare repository to other , then instead of doing push from source to destination , you should do a pull from destination to source.
Above mentioned explanation is what I understood after reading lot of resources over the internet and I just tried to write in simple terms for my future reference and other readers of my blog.

Comments and corrections are highly appreciated.


Saurabh Jain

A Developer working on Enterprise applications ,Distributed Systems, Hadoop and BigData.This blog is about my experience working mostly on Java technologies ,NoSQL ,git , maven and Hadoop ecosystem.

Share and Enjoy

  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS

One thought on “Bare and Non Bare Repositories , .git directory and working tree

Add Comment Register

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>