Purpose of branches in Git
Tags: git, branches, bestpractices
Published: 2020-08-31 17:32:55

Hello everyone! How are you all doing ? Now it's time to tell you about branches in Git, it's a bit obvious, almost every of you know what is a branch and how to use them, but there is a nuance, not every of you use it correctly as it supposed to be used and probably do not know *how to create, delete, restore* it. So in this post, I'll show you how to do it. 

## What is actually a branch ?

So the branch is a lightweight movable pointer to one of commits in your repository, by default you're given a **master** branch which also points to the last commit you'd made. Everytime you make commits, the pointer of **current branch** moves forward automatically and it's not a special branch, you can also create them. It's mostly used for making backups of certain version of the sotware *(just in case creating a copy of a branch)* or split up the development process, dividing the feature from each other, not worrying about other things to happen in the project, but only to focus on a thing you're working on. When you create a branch upon your **master** branch, your last commit on your new branch will be the last commit of your **master's**, which means that you just copy the branch that you were on. To create a branch, you just do:

```bash
git branch <branch-name>
```

and to checkout them, you need to do:

```bash
git checkout <that-branch-you-created>
```

but there is a better way of creating them and checkouting them at the same time, and almost every of you guys know that, just say:

```bash
git checkout -b <branch-name
```

The option `-b` says to `checkout` *"Hey man, I'd like you to first of all create a new branch with this name, and then checkout it"*

To view all branches, you can do:

```bash
git branch -a
```

which will view all branches, either remote or local ones. Understanding the difference of remote and local branches is obvious, you are going to face something like this:

![](https://i.imgur.com/dw4dd7h.png)

As you can see the current branch is highlighted with *green color* and remote ones are highlighted with *red* one. Also near the current branch you probably can see star sign (*) on the left side. For viewing only remote branches, you need to say something like this:

```bash
git branch -r
```

Here is the result:

![](https://i.imgur.com/DkqLpk9.png)

As you can see that we have a few remote branches which starts with *prefix* of **origin** and as you can see **origin/master**, the remote version of our *master* branch.

But it's a boring, don't you think ? Let's move on.

## Deleting the branches

Deleting is obvious process in git, let's say, you created a branch, worked on it, merged it, and want to remove it properly like *"I don't need you"*, and to do that, just say:

```bash
git branch -d <branch-name>
```

The `-d` option is the shortcut of `--delete` and it has a bit sense of humor, the git will tell you to use `-D` option, had ever thought about of existence of `-d` option then ? Like *Why the `-d` option exists when it tells you to use `-D` one ?* and that's because git makes sure that these branches are the same (the commits) (are they merged) and if they are, `-d` option will delete the branch, but if not, `-D` option will delete it. It's like git warns you to make sure that you're not removing the wrong branch, it's like git hints you *Man, are you sure ? Please rethink what you want to delete*.

![](https://i.imgur.com/BYVN8cr.png)

And of course there are times when indeed you don't need the certain branch in your local machine, so to properly delete that, use `-D` option, which is shortcut of `--delete --force`, like this:

```bash
git branch -D <branch-name>
```

![](https://i.imgur.com/L6lS1eh.png)

Git tells us that the **feature** branch is deleted which its last commit hash was **a658359** that also can be restored, the stuff I'll tell you a bit later.

In examples above we'd viewed the remote branches and somehow, some time maybe we want to delete the remote branch on our local machine, the default deleting branches with `-d` won't work:

![](https://i.imgur.com/slehqVh.png)

Git is looking for **origin/feature** branch in our local machine that indeed doesn't exist, the **origin/feature** branch is a remote branch, to delete the remote branch in our local machine we need to say:

```bash
git branch -r -d origin/feature
```

And surely git reports us the last commit's hash of the remote **origin/feature** branch

![](https://i.imgur.com/zvHn0O7.png)

### Deleting branches in remote repository

Had you ever been thinking: *So I deleted a branch, in my local machine, but how can I delete it in my remote repository, how to do that ? because I don't know how to push infomation on deleting certain branch there*. And so the answer is, you can do that in a certain ways:

```bash
git push -d <remote-name> <branch-name>
```

Either the above, or below:

```bash
git push <remote-name> --delete <branch-name>
```

And one more which might be easier to remember:

```bash
git push <remote-name> :<branch-name>
```
![](https://i.imgur.com/h1bW8Ep.png)

## Restoring branches

Sometimes odd things are going to happen. For example you accidently deleted the branch  you've been maintaining for a certain amount of time, you go:

```bash
git log
```

but nothing is there. Fortunately I got good news to tell, there is an option, you can actually restore the branches you'd deleted. The question you'll ask:

> How can I do that ? There is nothing in `git log`, My memory isn't good enough as Sherlock's or Ron White's to be able to remember the commits' hashes. So how can do that ?

We can use an amazing command, `git reflog`

```bash
git reflog [show] # you can add "show" or not, it'd work anyway
```

And after `show` you can specify branch's name, it accepts all kind of arguments which `git log` does.

What it does here, it simply shows the repository records, what did happen, on what branch, from where to where someone checkouted and so on.

For example we want to see the records owned by `master` branch, just say:

![](https://i.imgur.com/Z0uqLJg.png)

it says that nothing else beside of cloning from github was done. Let's move on.

Our purpose is to restore some branch, let's create a new one.

```bash
git checkout -b feature
```

And add some "feature" there, it doesn't matter what we'd add, the main thing is to restore it successfully, we just open the terminal and say:

```bash
echo "Hello World!" > feature
```

What it does, is we just simply create a file with "Hello World!" in it. Commit it. And just do:

![](https://i.imgur.com/LSHStLf.png)

We commited the *feature* file with **feature stuff** commit message.

`-v` flag shows branches with their names and the `HEAD`'s hash. Last commit of it. Checkout to `master` branch and delete the `feature` branch.

Let's make sure it doesn't exist:

![](https://i.imgur.com/PUELY7F.png)
The only branch we do have, is `master`. So what now ? For instance you accidently delete a branch, or remembered that there is certain piece of code that is needed. `git log` won't help, because it shows only commits of current branch and when you specify as a first argument the *deleted branch's name* it will simply tell you that it doesn't exist. To restore the branch we need, tell the terminal the following:

![](https://i.imgur.com/BqZ8p2t.png)

Here we see all stuff which happened in this repository, in our local machine. So we see some stuff associated with desired branch's name, *feature*, the thing is **to find the commit hash where it was last time used**. And here it is, I'll show you how:

![](https://i.imgur.com/5HiOANr.png)

That is the last commit that was made on *feature* branch, to understand how I got that, just see the text above, it says:

> HEAD@{3}: checkout: moving from feature to master

Which means that job with feature branch is done. 

So what's next ? We do know the commit's hash, what to do next ? We can restore it with `git branch` command, or `git checkout` it doesn't matter.

![](https://i.imgur.com/0WtyDKx.png)

So here we're restoring the branch by its commit hash. As the second param goes hash of the commit. So we did restore the branch we desired.

`git branch` and `git checkout` are powerful commands, their purpose is not only *creating*, *deleting*, *restoring* branches, but it can also let's say retrieve the file to certain version of it. What do I mean ? I mean that we can specify a certain file, for instance *index.html* or *work.html* to be resetted to a certain commit, where and how it was then.  Do not reset all files, but only one (or a couple) to older version.

For example, that's re-checkout to our master branch:

![](https://i.imgur.com/Qb1d65r.png)

`-` sign after `checkout` checkouts to a branch we switched from, which is `master`

![](https://i.imgur.com/8emsclE.png)

Here is the list of master's commits. For example I want to change the file to version that has no *"blog"* element in the menu, to do I just grab the commit's hash of this:

![](https://i.imgur.com/ly85TC4.png)

Because, after this commit as you can see the *Blog* element is added, so we do:

```bash
git checkout eb72515 index.html
```

![](https://i.imgur.com/6aKJkoe.png)

As you can see checkout command didn't effect our repository, but only changed the *index.html*, made older.

![](https://i.imgur.com/vqFg9qX.png)

Also after *checkouting* the *index.html* file, the file automatically is added to **index**, we can commit changes by:

```bash
git commit
```

To remove the file from index to *Working directory*, just remember the *reset* command:

```bash
git reset index.html
```

## Best practices

Better using of branches is obvious and can make your, co-workers' lives easier to understand what is what and where it is. 

When you're working on the certain feature, make a branch with the name of the feature, and commit every single thing you did, don't make fat, large commits, just try to make them simple to read and understand. If you want to explain what did you do in a commit, remember, commit consists of two things:

- **Title**

- **Description**

The **title** is the first "field" of commit and second is **description** "field"

![](https://i.imgur.com/C69YstN.png)

The **title** must be short, and **description** can be as long as you want.

So here it's for this post, I'm glad that you read this, hope you learnt something from my post, stay tuned, **farewell**.

This post firstly was posted in my [blog](https://mrcat323.github.io/blog/purpose-of-branches-in-git/).