Git, but not dumb down: Local branches
Tags: git, github, beginners, tutorial
Published: 2020-09-03 11:34:03

# Introduction
<!-- Introduce the topic: BRANCHES -->

Welcome back! Be sure to check out the first past of this  series before you jump into this one.

Let's start with a brief reminder of the last post:

> **To summarize**: every time we stage a file, a blob object is created, storing the content of each file. Its name is the SHA-1 of the file's content and it’s stored under <code>.git/objects</code>. Whenever we commit the changes to the repository, we create two new kinds of files: a tree, which stores more information about the files changed under it and a commit, with all the information about who saved the snapshot and why (the message!).

We took a quick look at the <code>.git/objects</code> folder in your repository in our last post. Today, we are going to look at <code>.git/refs</code> and the concept of **local branches**. 

## Branching
<!-- An overview of the subject, ref files. -->

First, we need a new repository (practice makes perfect):
![git init](https://dev-to-uploads.s3.amazonaws.com/i/sqfzh6m97kq6tkm12fqv.png)
![git add new file](https://dev-to-uploads.s3.amazonaws.com/i/nqvpdyr6ng8hfhxofgn5.png)

Now that we have a working repository, we can introduce a little bit of theory. A branch in Git is simply a lightweight movable **pointer** to one of your commits. The default branch name in Git is *master*. As you start making commits, you’re given a master branch that points to the last commit you made. Every time you commit, the master branch pointer moves forward automatically.

Internally, a branch is just a file in your <code>.git/refs/</code> folder that contains the SHA-1 id of a commit. Before we commited the *new_file*, this was the structure under <code>.git</code>:

![tree -a .git](https://dev-to-uploads.s3.amazonaws.com/i/643p77ixhw4w7k1fpvvd.png)

And this happened after the commit:

![tree -a .git/refs](https://dev-to-uploads.s3.amazonaws.com/i/omlf366z3m42xv0eh5g8.png)

Can we take a loot at that <code>master</code> file? Of course!

![cat heads/master](https://dev-to-uploads.s3.amazonaws.com/i/ccjasdq250izhyer9gvo.png)

If we take a look at the log, just to be sure, we can see that it is in fact the id of the first commit that we made.  

To get some content in our repository, and to check that what we just said really works, let's add another file:

![git add second file](https://dev-to-uploads.s3.amazonaws.com/i/vfr493p9wan0cnrhbz15.png)

![git log 2](https://dev-to-uploads.s3.amazonaws.com/i/1z5658q1imk4gmzv05qw.png)

![cat master 2](https://dev-to-uploads.s3.amazonaws.com/i/vatzm14lw57n0txwtzdz.png)

### HEAD

We have confirmed that the pointer "moves" whenever we make a commit, so let's bring another branch into this:

![git branch new_branch](https://dev-to-uploads.s3.amazonaws.com/i/1rm8b28ysvfm8wfjy7qi.png)

We used the <code>git branch</code> [command](https://git-scm.com/docs/git-branch) to create a new branch. Can we just add commits to it?

![git add failed file](https://dev-to-uploads.s3.amazonaws.com/i/aqc6nfo0xqx6amh0b2az.png)

![git log failed file](https://dev-to-uploads.s3.amazonaws.com/i/vhh5dx5ydffs2b5w0cw4.png)

![cat master 3](https://dev-to-uploads.s3.amazonaws.com/i/1qsyj3yf2vp8mio6i1bs.png)

What happened there?

1. We got a new file called *new_branch*.
2. We made a new commit that was supposed to be on the new branch, but!
3. We found out that both new_branch and master point to this last commit.

Why did *master* update? Creating a new branch doesn't mean you are working on it. Git utilizes a special pointer called **HEAD** to know in which branch you are working on. If we take a look at it, before we switched branches

![head before checkout](https://dev-to-uploads.s3.amazonaws.com/i/1psmnk9hhu8cyk9ix0hf.png)

we can see that it contains a reference to another reference, in this case your **master** ref file. We'll use the <code>git checkout</code> [command](https://git-scm.com/docs/git-checkout) to switch branches and add a new file to test it:

![git add good file](https://dev-to-uploads.s3.amazonaws.com/i/i9fglq9w99ipxs3c87wm.png)

![head after checkout](https://dev-to-uploads.s3.amazonaws.com/i/259661qlyxcal1rca3mf.png)

HEAD updated to the new branch after <code>checkout</code>. You can look at this on your log too (HEAD -> *current_branch*):

![git log after good file](https://dev-to-uploads.s3.amazonaws.com/i/wday1i5oticny83mvkdl.png)

## Merge

After we looked at how we can diverge our work, we'll take a look at **merging**. The <code>git merge new_branch</code> command will replay the changes made on the *new_branch* branch since it diverged from *master*  until its current commit on top of *master*, and record the result in a new commit. So what happened to our ref files?

![git merge](https://dev-to-uploads.s3.amazonaws.com/i/9mpflc4l8u3s81ajzkn6.png)

Now the both point to the same commit, and HEAD still points to *master* from the checkout. If we continue working on this branch, we can see in our log that *new_branch* will be left behind.

![final image](https://dev-to-uploads.s3.amazonaws.com/i/be7h4fz250a1mah2znmm.png)

## Workflow

Now that we introduced the basics of branching, we'll take a look at a couple of git workflows. First, you must know that **there is no standardized process on how to interact with Git**. You can commit after each new word on a file, or make and merge branches for every file, for all Git cares. **Use it however works for you and your team**.

### Feature branch
![feature branch worflow](https://dev-to-uploads.s3.amazonaws.com/i/rj78nmkdjcxrxibv9tiv.png)

> *The core idea behind the Feature Branch Workflow is that all feature development should take place in a dedicated branch instead of the master branch. This encapsulation makes it easy for multiple developers to work on a particular feature without disturbing the main codebase.*

> From Atlassian's [Git Feature Branch Workflow](https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow)
<!-- -->

Its just that simple! Whenever you need to add some feature to your project, you checkout a new branch, commit anything that you need there, and then *merge* it into the main branch.

### Gitflow

![Gitflow](https://nvie.com/img/git-model@2x.png)

This workflow is the idea of [Vincent Driessen](https://nvie.com/posts/a-successful-git-branching-model/) on 2010. You really should read that post, as its really nicely explained!

Gitflow doesn’t add any new concepts or commands beyond what’s required for the previous workflow. It assigns very specific **roles** to different branches and defines how and **when they should interact**. In addition to feature branches, it uses individual branches for preparing, maintaining, and recording releases.


# Future notes
After this post, the plan is to continue the branch topic with remote branches, reset, and rebasing.

I'm interested to know what do you think, if you have any comment or suggestion! Thanks for stopping by, see you again soon!