What Is a Git Branch? (Simple Explanation)
If it's your first time learning about Git branches, Google results can be a bit disappointing. All you get is that "branches are pointers to commits," and abstract stuff like that. So let's simplify. Let's read about Git branches explained in simple terms.
What Is a Git Branch?
The (boring :) technical explanation for a Git branch is that it's a "pointer to a commit". And this pointer moves around as we add new commits within this branch. Always pointing to the latest commit (within the branch).
But this kind of technical explanation is quite abstract. Let's explore it in more down-to-earth, practical terms.
Let's imagine we are visiting Tokyo. And we create a folder on our laptop to store all the photos we'll take. Every day we keep adding new pictures to this folder.
Our folder has a few nice properties:
- It groups all the photos for this specific vacation.
- It creates a timeline for our vacation. Meaning, if we look at our pictures in the order they were created, we can see what we did each day – how our vacation evolved, step-by-step.
- The last photo in our folder will show us how our vacation has ended (last state).
A Git branch has very similar properties to a folder. You see, Git also has its own version of "photos," called Git commits. A Git commit is like a photo for our code / project.
Whenever a team member changes our project in some way, he / she can make a commit. And this will make a snapshot of the entire project. If we look at that commit, we'll see exactly how the code / project looked like at that time, after that change.
Now we can see why a Git branch has similar properties to a folder:
- It groups commits created for a certain purpose. For example, all the commits that were made to fix bug #39.
- It shows us the timeline of the commits. We can see, step-by-step, how code evolved within this branch. What exactly was done to fix bug #39?
- Just by switching to a branch we can see the last state that was reached when working for a specific purpose. We can see "progress made so far" to fix bug #39. Or progress made so far to add a new feature.
Why Do We Need Git Branches?
Imagine one team creating a chain of commits as they work on a bugfix. And a different team creating another chain of commits as they work to add a new feature.
Without branches, all of these commits would be mixed together. It would be like keeping all of our photos, from the last 10 years, in a single folder. We wouldn't know where to find our photos from Rome, and where to find our photos from Tokyo. Or, in this case, where to find commits for the bugfix, and commits for the new feature added.
Branches isolate work according to purpose:
- We move to one branch, we'll see the last state our code was in when developers were working on a bugfix. And the chain of commits they went through to get there.
- We move to a different branch, we'll see the last state our code was in when developers were working to add a new feature. And the chain of commits they went through to get there.
Just like in a folder with photos we can see the last picture, showing us how the vacation ended. But we can also see the pictures before that, showing us how we got to that point in our last picture (the places we've visited, the roads we've taken).
So a branch will have the last state of our code, built for a certain purpose. But also the "development road" code went through, until it got to that point.
Besides, without branches, how would we add a new feature to an application?
Think about this. A Git repository usually has a default branch called master
. Very often, this master
branch will be used to keep a record of commits for our "clean code," or stable version of our application.
Now let's imagine the code for our stable version looks like this (in our master
branch):
// Main application code:
line1
line2
line3
But, now, we want to add this new feature:
// New feature:
line4
line5
What do we do? Do we simply add this code on top of our main code in the master
branch?
Not the best idea. In the real world, this new feature might need hundreds, or thousands of lines of code. And it could require days, or weeks of writing new lines. Also, that new code has to be tested before being released to the public.
Imagine if we would add our changes directly in the master
branch. At one point our code could look like this:
// Main application code:
line1
line2
line3
// New feature:
line4
Notice that line5
is missing. It's just too much work, and the developer could not add all the new content today. So now we have an incomplete project in our master
branch. Maybe just the bare minimum to start testing ideas for this new feature.
And even if line5
would have been added. What about potential bugs? What if line5
is causing issues and it needs to be fixed?
We can't add rough, unpolished code to our main master
branch until we're certain everything works properly.
Not to mention that other teams could be working on other features, or bug fixes. If 30 different people would just directly change code in the master
branch it would be a mess. Imagine hundreds of lines of code being added, modified, removed, in the same place! People would constantly step on each other's toes.
Branches allow us to organize work. And separate it into small, well-defined compartments.
We can create different lines of development, for different purposes.
- If we switch to one branch, we can see work on some bug fix.
- If we switch to another branch, we can see lines of code added for a new feature in our app.
Each branch has its own purpose. And everyone can work in their own branch / compartment without fear of breaking the well-polished code from the master
branch (or other branches).
Finally, when work in a branch is complete, and tested, we can "assimilate" it back into our main master
branch with a git merge
command. As we can see in this blog about how to create Git branches.
If you're more of a visual learner, we also have this Git Course for Beginners: