In previous post, we discussed on the commit variations. Basically, we discussed how to stage changes selectively or whole and then committing those changes. We also discussed how to amend previous commit as well and understanding its command line equivalent git commands. In this post, we are going to discuss about concept of branching in git and how it works.
Concept of Git branch and master branch
To understand about git branching, we need to revisit few concepts that we have already discussed in previous blog posts related to integration of git and visual studio. If you may remember correctly, Git does not exactly stores data as series of changesets or deltas, but instead as series of commits.
When you make a commit in Git, Git stores a commit object that contains a pointer to the snapshot of the staged change, few other details such as author, commit message and previous commit information.
To consider an example, let’s revisit our commit history that we created for project ConsoleApp02. For this, we’ll open git bash shell and run command ‘git log –oneline’. This will allow us to view one commit per line:
Let’s get details of last 2 commmits by running git cat-file command. This will throw us below output:
In last commit, the parent value is the hash of last 2nd commit. Similarly, in last 2nd commit, the parent value is the hash of last 3rd commmit.
A branch in Git is simply a lightweight movable pointer to one of these commits. The default branch name in Git is master. It is created as soon as you create your first commit in the git repository. Every time you commit, it moves forward automatically.
If trying to understand in a visual manner, it looks like this:
Create new branch in Git
When you create a new branch in Git, it creates a new pointer for you to move around. Let’s say you create a new branch called development. You do this with the command ‘git branch development’.
This creates a new pointer at the same commit you’re currently on. Once its created we can checkout the same by using command ‘git checkout development’:
Checkout essentially informs git that we are going to work on the new branch created.
Concept of HEAD and its usefulness
Git has to know which branch we are working on so that it can create and keep track of the commits properly. For this purpose, it keeps a special pointer called HEAD. In Git, this is a pointer to the local branch you’re currently on.
If we run git log command, we can see that HEAD is now pointing to new branch as we switched to it:
In visual terms, it can be understand like this:
Understand switching of branch and HEAD position
Let’s add a class file to our development branch and make a commit:
If we see git log now, we can see that we are ahead of master branch by one commit. Also HEAD is now pointing to new commit:
Let’s switch back to master branch by running ‘git checkout master’ command. If we run git log command now, we would get below output:
That command did two things. It moved the HEAD pointer back to point to the master branch, and it reverted the files in your working directory back to the snapshot that master points to. This also means the changes you make from this point forward will diverge from an older version of the project. It essentially rewinds the work you’ve done in your development branch temporarily so you can go in a different direction.
So in a nutshell, a branch is just a simple file which contains the pointer to commit. So its very easy to create and destroy branches in Git.