These 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
git add my_first_file git commit –m “My First Commit” my_first_file
So, 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.
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.
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
at your remote repository , you will see something like this as expected.
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.
Latest posts by Saurabh Jain (see all)
- java.lang.IncompatibleClassChangeError: Found interface org.apache.hadoop.mapreduce.TaskInputOutputContext, but class was expected - August 8, 2014
- org.datanucleus.store.rdbms.exceptions.MappedDatastoreException: INSERT INTO “TABLE_PARAMS” – Hive with Kite Morphlines - July 17, 2014
- java.io.IOException: can not read class parquet.format.PageHeader: null – Hive - July 12, 2014