Git and Github: The Complete Guides - Chapter 5: Merging Branches
Tags: git, github, webdev, beginners
Published: 2021-09-21 10:49:37

![goran-how-u](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jomdxhgflzazcd9rjani.png)

We are now able to create different branches in the local repository as well as different branches on our remote repository (GitHub). In the real world when you create different branches and work on them, eventually you need to combine them with the master branch. This process is called **Merging** branches.

We will be discussing how to merge branches, the different types of merging and also some of the conflicts that might occur when merging the branches.

**Here we are going to cover:**

<ul>
<li>Git Merge (fast forward)</li>
<li>Git Merge (3-way-merge)</li>
<li>Merge Conflict</li>
<li>Git Rebase</li>
</ul>

![Altbext](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pp9uxa5rm3bp3bj7t373.gif)

##Git Merge (fast forward)

Firstly, lets go to our local repo and see which branches we have. Then lets look at the history of our commits so we know where we are. Finally lets create and switch into a new branch, lets call it **_playground_**.

After creating and switching into our new branch lets modify the style.css file and save the changes. Now we can **git add** these modifications to the staging area and finally make our **git commit**.

####Did you know?
There is an easier way to ``git add`` and then ``git commit`` our file. This chapter is all about merging so it's appropriate to merge these two commands we use so frequently.

We can use the command:
```
git commit -am
```
This command is followed by the commit message. Now we are adding our file to the staging area and making the commit simultaneously!

>**This is a shorter way**, but just remember that this command only works for modified and deleted files. If you have new files which are not tracked, this command **will not work!**

![git-merge-1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jk3i5olmpraw15ccjvdk.gif)

We can make another commit for good measure. We can modify the style.css file again and this time change the color of the paragraph and save. Finally add and commit our changes.

![got-merge-2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xfm3yzgx9mee8zmj1nkn.gif)

As you can see the **playground** branch is now two commits ahead of the **master** branch. So now lets say we are happy with our changes and we want to merge those two branches. At first we need to switch to the **master** branch.

We will see our **master** branch does not have the changes we made on the **playground** branch and we can confirm this by checking the history of our commits. You will see that the two commits we made are not in the **master** branch commit history.

![git-changes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j3g3fj4d05t8qf6yqvqh.gif)

To merge these two branches we need to run the command:
``` 
git merge
```

This command is followed by the name of the branch you want to merge with the **master**. For example:
```
git merge playground
```

![git-merge-success](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5301ojc1lmkhy917e6be.gif)

This command has now merged our two branches and if we look at our logs ``git log --oneline``. We will see that **HEAD** now points to both branches, **master** and **playground**.

Awesome stuff👌

We have successfully combined two different branches and this type of merge is really basic and it is called <u>fast forward</u> merge.

In the case of a <u>fast forward</u> merge, there is a linear path from the **master** branch to the second branch, which in this case is **playground**. The **playground** branch is created based on the last commit of the **master** branch. Meaning while we were working on the **playground** branch, no commits were being made to the **master** branch.

When we use the ``git merge`` command, all the commits from the **playground** branch were added after the _**base commit**_,<u> which is the last commit of the master branch </u>.

![git-merge](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m01ln1w0l9sp8n40fhjs.gif)

Therefore any changes made to the **playground** branch will overwrite the old state of the **master** branch and there won't be any conflicts.

To prove this, lets switch back to the **playground** branch. Make a modification to the style.css file and save it. Then make a new commit. We can then go back to the **master** branch and run ``git merge playground`` again.

![git-merge-again](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ayxws85lfy5zp5audcqr.gif)

That is the way we can merge two branches in a <u>fast forward</u> way. There is another type of merge which we are going to discuss next.

##Git Merge (3-way-merge)
The other type of merge we can perform is called the <u>three-way merge</u>. This kind of merge occurs when we create a new branch, work on that branch...Then simultaneously someone else makes commits on the **master** branch before we merged the two.

![git-merge-3-way](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ct2vubea8p9akxzcrps6.png)

Actually this is pretty common and knowing how to work with this type of problem is **essential**. So lets simulate this kind of scenario by making two changes in our script.js file in our **playground** branch, finally adding and commiting the changes.

![git-merge-playground](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0cfe6xrxbldn9g02o466.gif)

Switch to the **master** branch, make a different change in the index.html file and then add and commit the change.

![git-merge-master](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/letdsf6caz2mfzqw4jm8.gif)

>Don't forget to log the history of both branches once you've made your changes to see the differences.

Now suppose we want to merge these two branches. In this case we will no longer have a <u>fast forward</u> merge because we've been working on both branches simultaneously. So lets go ahead and **merge** these two branches.

Run the command ``git merge playground``

![git-3-way-merge](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xkcvzbi9z2nmzk0ie6dk.gif)

As you can see we are greeted with a new file in the editor, also Git is hinting to us that it is waiting for us to close the file in the editor. We don't need to do anything in this file for now, so we can quit out of it and close.

![git-3-way-merge](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iuifqzq7du2nq48hm0g5.gif)

We can see our merge performed successfully, however on closer inspection, we can see it is a different type of merge which is called <u>three-way</u> merge. After the merge it says **_merge made by 'recursive' strategy_** which is the default strategy of a <u>three-way</u> merge.

Now all the changes we made on the **playground** branch is available on the **master** branch as well, unlike the <u>fast forward</u> approach **_HEAD_** points to **master** and not to both branches. 

That is why we see only **master** next to the **HEAD** pointer and not both branches like we did before.

If we switch to the **playground** branch we will see the index.html file was not modified in our commit history and we will find only the commits we made on this branch.

![git-merge-3-way](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9t0xgva57q9bwywxnh4f.gif)

####How it works?

When we create a new branch, make some changes/commits to that branch, then simultaneously someone else makes commits to the **master** branch. It means we no longer have <u>fast forward</u> merge, instead we now have a merge type called <u>three-way</u> merge.

In this case Git will help us by checking for any conflicts in the file because people may work on the same files. If all is good then those changes will be merged to master and the commits will be place in a sequence in history.

This is the case when a <u>three-way</u> merge occurs.

![git-merge-3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dcbruk47kx6pa8hibivq.gif)

Seems like Git solves our issues for us but we can still run into some **merge conflicts** dispite Git's best efforts.

##Merge Conflict

Sometimes multiple developers may try to edit the same content. For example, if one developer is trying to edit code that the second developer is editing. Then merge conflicts can occur.

Merging and conflicts are a common part of Git, in other version control systems it is slightly harder to deal with merge conflicts but Git make this easy for us. We can simulate how a merge conflict may occur and how we can deal with them.

Firstly, lets go to our project and see all our branches. Currently we have two branches, namely **master** and **playground**. We are working on the **playground** as indicated by the green color. Lets say we want to modify the variable in the script.js file in our **playground** branch. We then save our change and make a commit.

![git-branch](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j8em3cr3989u6hnhrsir.gif)

Now lets say someone else is editing the same script.js file on the same line but he/she is working from the **master** branch. We can simulate this scenario like we did before. 

We will first _switch_ to the **master** branch, change the name of the variable in the script.js file and save, we will commit this change to history and finally log the history.

![git-branch-1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tt8edrzjc56fybsiz5l9.gif)

Suppose we need to merge these two branches, when we run the command ``git merge playground`` Git will tell us that there has been a **merge conflict**. This is because we have been working on the same line in different branches, so Git was not able to decide which line/version it needs to keep.

_Therefore a conflict has arised._

As you can see both versions are present in the script.js file as well as some code that Git inserted.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9n6gu5hfylqbfs46b9wa.gif)

To resolve this problem, we first need to remove the code Git has added and then we need to decide which version of the code we want to keep.

After that we need to add the file to the staging area. Like this: ```
git add .
```

Then we need to make a commit, but in this case we just need to run the command without any message: ```
git commit
```

Now a new file will open in the editor, like in the case of a <u>three-way</u> merge. Here we can change the message of the commit if we want. 

![git-branch-commit](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9n6gu5hfylqbfs46b9wa.gif)


####When we close the file, the new commit will be made. The branches will be merged and the conflict will be resolved.

If we run the history we will see **merge branch playground** which means we have merged the branches successfully.

Awesome😎!

####Now lets see how we can stop a _merge conflict_.

As we did before, we will be simulating two developers making a change on the same line of the same file, but just from different branches. 

![git-commit-branch](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z4bds3oqhvwm7uae54e0.gif)

We will again use the script.js file and make some changes and commit them to history. Finally after editing the script.js file on both branches we will run the command ``git merge playground``.

![git-branch-merge-abort](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l0dms9dcj44vvwdhb7m0.gif)

Now suppose we want to stop merging. To do this we need to run the command: ```
git merge --abort
```
####Git will stop the merge from happening, there won't be a merging conflict anymore and both changes we made on the two branches will be kept.

In the real world, these types of conflict appear quite frequently but thanks to Git they are easy to deal with.

Before carrying on we can resolve the merge conflict we just had.

![git-merge-success](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2szlv49ofassmvckcrxk.gif)

##Git Rebase

We are now familiar with the **Git Merging** and how to resolve merge conflicts, it is now time for us to discuss another feature of Git which is called **Git Rebase**.

![git-rebasing](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i6w473w7qf9nx1ko9mr3.gif)

Suppose we have a couple of commits on the **master** branch, then we create a new branch and add some commits to it. Then after that we create a new commit on the **master** branch.

In this case, by default _base commit_ is the commit from where we created a new branch. But by using **Git Rebase** we are able to change the _base commit_, essentially rebasing our branch on the newly created commit on the **master** branch.

>After Rebasing, all the changes we made on the master branch will be available on the second branch as well.

_In order to make things look a little cleaner, I am going to delete some of my commits by using ``git reset --hard``_

![git-reset-hard](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dtlhc1pzss1s0ikv041b.gif)

_Next I'm going to delete the playground branch and create a new branch called **newBranch**._

![git-newBranch](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t83pw7pbarkdi9tkyvqv.gif)

When we look at the history of our commits, we see that **HEAD** points to **newBranch** and **master**. This means that they have identical histories.

![git-history](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eyp2om6zmqlzwety8egj.gif)

Lets switch back to the **master** branch and make a new commit. For example, we can modify the style.css file and change the size of the h1 tag. We save and then commit this change.

If we log the history again, we see that the **master** branch is now 1 commit ahead of the **newBranch**. This means that this new commit won't be available on the **newBranch**. We can switch to the **newBranch** to confirm this by running the command ``git log --oneline``.

![git-branching-rebase](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/igpwhudpxyy8jg8m8lgx.gif)

If we want to make the last commit from the **master** branch available on the **newBranch** as well, we can use ``git rebase`` which will allow us to rebase the **newBranch** on the newly created commit which was made on the **master** branch.

We do this by running the command:
```
git rebase master
```

Now when we log the history, we can see **HEAD** points to both branches, **newBranch** and **master**. It means that the last commit from the **master** branch is available on the **newBranch** as well.

![git-rebase-newBranch](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a6ze2w2s2g7fem68bsq8.gif)

Lets consider again how ``git rebase`` works using a different scenario. We start by making a couple commits on the **newBranch**, then we log the history of our commits.

![git-rebase](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/canwzvviq4u39snn8fh6.gif)

Lets switch back to the **master** and make one commit. When we save our change and make the commit, if we check the history we see the commits of the **master** branch but not those for the **newBranch**. 

To address this we switch back to the **newBranch** and _**rebase**_ it to the last commit made by the **master** branch. After we _**rebase**_ the **newBranch**, when we check the history of commits, we see the last commit made by the **master** branch as well as the two commits we made on the **newBranch**.

![git-master-rebase](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k75gp46wcvig622sk1ap.gif)

Now all the commits are available on the **newBranch**, but if we go to the **master** branch and check the history, you will find that we still have the commits we made only on the **master** branch.

In order to make commits on the **newBranch**, available on the **master** branch as well, we can **merge** those branches by running the command ```
git merge newBranch
```

As you can see the branches are merged. You may notice that instead of a <u>three-way</u> merge, we instead have a <u>fast-forward</u> merge. This is because we rebased the **newBranch** on the last commit of the **master** branch, that is why Git used the <u>fast-forward</u> merge.

<hr>


That's it! I hope you enjoyed and gained something from this chapter. 

😃See you when I see you. 
![see-ya](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mw5b6xu5ge5brtxbzhqw.gif)