Git For Beginners - Part 2
Published: 2020-08-19 19:13:36

This series is aimed to simplify the concept of git for beginners. In the first Part we've discussed about the basics of different working areas, different scenarios involving adding and committing changes to our repo.

We will continue with our approach of looking into various used cases, instead of just memorizing git commands.

Before going into that there was something about the git objects that I'd missed in my earlier post. We saw how the commit object stores info about the previous commits, so every child commit has a pointer to the parent commit and thus a linkage is established. 

But can't this be the other way round? There could be a possibility that the parent commit stores pointer for the child commit. However this isn't something that is being followed because the git objects are immutable. So they can't be edited once they've been created. Hence any chance of parent storing child commit pointers get nullified. 

## Creating Branches:
Branch is just a pointer to any commit. Branches are required to work in parallel towards multiple issues related to a project. The default branch that gets created with our repo is called __master__.

Every time we commit, the master branch pointer moves forward automatically.

```git branch <branch_name>```
This command can be used to create a new branch.

However the above command just created a new branch, but it won't automatically get switched to this branch.


```git checkout <branch_name>```
This command checks out the newly created branch and we can begin our adding our files and commits to this branch.


```git checkout -b <branch_name>```
Most often than not, we want to create a branch and switch to it simultaneously i.e. combining the work done by the first and the second commands. 

## Merging Branches:
Suppose we've created a new branch to work on any enhancement of the project. Once the development of the same is completed, we would want to merge it with our initial branch i.e. master.

But before that we can check what all are the differences between the master and our new branch by the following command:
```git diff master..<new_branch>```

There are 2 types of merges namely __Fast forward merge__ and __Three way merge__. Fast forward merge is when we try to merge one commit with a commit that can directly be reached by following the first commit's history, thus git directly moves the pointer forward as there isn't any diversion in the path of merging.

In case of Three way merge, the development has diverged somewhere from some past commits in either of the branches and thus a Fast forward merge is no longer possible. In this case Git performs a three way merge using the two snapshots provided by the branch tips and common ancestor of the two branches. Instead of just moving the pointer ahead as was the case in fast forward merge, git creates a new snapshot (commit) and this is called a merge commit. 

The MERGE_HEAD pointer points to the head of the other branch. (The one getting merged)

steps for merging:
- Checkout the branch where you wish to merge into:
```git checkout branch1```
- merge the branch
```git merge branch2```

## Squash and merge:
At times, there might be multiple commits in a branch but we wish to merge them as a single commit in our master, in such a case we opt to squash the commits.

Will group all feature branch commits into one commit then append it in the front of the master branch. Will add an extra dummy commit.

steps for squash and merge:
- Checkout the branch where you wish to merge:
```git checkout branch1```
- merge the other branch
```git merge --squash new_branch```

__Note:__ Squashing doesn't delete the original commits that are squashed to form the new commit.

## Re-base:
The strategy used so far to merge branches works absolutely fine. However the commit history is all messed up, esp. if there are multiple people working.

To avoid this issue, there is a cleaner way to merge the branches.

git re-base will append all commits history of the feature branch in the front of the master branch and won't add any extra dummy commit.

git forms a copy of the feature branch on top of the master branch, hence the name re-base.
steps:
```git checkout feature```
```git rebase master```
this would rebase the feature branch on to the latest commits of the master branch. So, this sort of changes the commit history for the feature branch.
```git checkout master```
```git rebase feature```

__Note__: Since git rebase changes the chronology of the commits, it isn't advisable to use it on commits which others depend on.

![git merge rebase image](https://i.stack.imgur.com/hUtiB.png)


## Deleting Branches

Most of the times after merging a branch, we don't need the branch anymore and that branch can be deleted.
```git branch -d <branch_name>```