In this article we will take a deep dive into Git branches. We’ll see how simple yet powerful the concept of branching in Git is. This article is part of a series of articles that will also be part of our book Rebase which you can and should follow it’s progress on Leanpup.
In our last Git article we took a detailed look on the anatomy of a commit. Now that we know how commits work in Git let’s expand on our knowledge and understand branches. It’s important to first grok the concept of branching in Git before we go into merging.
Starting with a simple scenario
Let’s start by looking at a simple commit history.
Let’s assume our entire repository history is made up only from those three commits. There’s a pointer called
master pointing at commit
a5c3eb. That’s all what branches are: they are movable pointers. Let’s create a branch called
git branch feature
Seen that? We just created another pointer called
feature pointing at the exact same commit. Basically, all Git does it creates a file called
feature with the contents being a 40 char string, the SHA-1 revision name of the commit.
But wait! Now that we have two different branches pointing to the same commit. How does Git know which branch is currently checked out? This is where the
HEAD pointer comes into play!
HEAD is a special pointer that simply points to the currently checked out branch or commit. And again, it’s a simple file inside the
.git folder called
HEAD which in our case currently contains the string master.
Ok then, what happens if we switch to our feature branch?
git checkout feature
Exactly, all what happened is that
HEAD is now pointing to
feature instead of
master. Switching between
feature at this point boils down to Git replacing the string master with feature in the HEAD file. Super cheap!
But what happens if we now create or modify some files and make another commit? Let’s find out.
vim file.txt git add file.txt git commit -m "yay, that's fun!"
We created a new commit
c57e22 and the
feature pointer moved on to it. That’s because branches are simply movable pointers to commits. But why did
feature move and
master did not? Because
feature is the currently checked out branch. And how does Git know? Because
HEAD points to
feature! Simple isn’t it?
Let’s switch back to
git checkout master
What happened now is that the
HEAD pointer changed to
master and the state of the entire working directory was changed to what it was at
Let’s modify a file and create another commit.
vim anotherFile.txt git add anotherFile.txt git commit -m "yay, more fun!"
A new commit
3aa2ff appeared and
master moved on to it. At this point our history has diverged. And this is the whole point of branches. They enable us to have parallel evolution of a code base.
At this point you may be wondering how to merge both ends back together. This is exactly what we will look at in our next Git episode. Stay tuned!
Ever came across a detached
HEAD? Now that we know how Git handles branches, it’s the perfect time to demystify the detached
HEAD. You’ll be suprised how simple it is. In fact, you may have spotted a hint in the text above.
HEADis a special pointer that simply points to the currently checked out branch or commit
Not only can we check out branches, we can also checkout any commit revision explicitly.
git checkout 339aa3
You see? What happened now is that
HEAD points to
339aa3 explicitly and the entire working directory was changed to what it looked like at that commit.
HEADpoints to a commit hash explicitly (rather than to a branch) it’s in a detached state.
What happens if we create new commits from here? Let’s find out!
vim someFile.txt git add someFile.txt git commit -m "detached HEAD fun"
Let’s add one more!
vim someFile.txt git add someFile.txt git commit -m "more detached HEAD fun"
We can go on like that. Does that mean, we don’t actually need branches? Yes and no. What we just did is kinda like having a branch without a branch name. It works but there are two problems:
How do you remember the SHA-1 key without a simple branch name?
Commits that are not reachable by any branch or tag will be garbage collected and removed from the repository after 30 days.
No need to worry though. We can simply create a new branch right here!
git checkout -b bugfix
Bottom line: If in doubt, just branch. Branches are too lightweight to even think twice about them.
Need a private training?
Get customized training for your corporationRequest quote →
Get updates on new articles and trainings.
Join over 1400 other developers who get our content first.
The anatomy of a Git commit
In this article we explore what a Git commit looks like internally and how Git uses cryptographic tooling to enforce...
Git Ninja Class in Amsterdam
We are very happy to announce that, with the help of our new partner De Voorhoede, we'll bring our Git...
Going back in time to split older commits
Rebasing in Git allows you to go back in time to split older commits. In this article we'll explore how...
Git Ninja Class comes to Istanbul
Today we are happy to announce that our Git Master Class is coming to Istanbul! Read everything about this event...
Tickets are on sale now!
It's on! You can now buy the first bunch of tickets for our Git Ninja Class workshop in Hannover, Germany!...
Announcing our first workshop
As announced earlier this month, we were working on our website to launch it as soon as possible. The time...