> For the complete documentation index, see [llms.txt](https://furkhan324.gitbook.io/workspace/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://furkhan324.gitbook.io/workspace/dev/git/merging-simplified.md).

# Merging Simplified

## Common Merging Confusion

A simple *fast-forward* merge is easy to grasp. It looks something like this:

```
             (C3)
            /    ^ HEAD,ISS:1
(C1) -> (C2) 
             ^MASTER
```

We merge our commits from ISS:1 branch into Master.

```
$ git stash/commit  #Let's clean up changes on ISS:1 before merging
$ git checkout master
$ git merge ISS:1
// master was fast-forwarded one commit
```

Our git tree now looks like this:

```
(C1) -> (C2) -> (C3)
                    ^ HEAD, MASTER, ISS:1 
```

But what about when the master branch has diverged from the commit you started ISS:1 from?

```
$ git remote add origin https://github.com/repo_name
$ git fetch origin master # Fetch the master branch in the origin repo
$ git checkout master
$ git merge origin/master # Merge remote master commits into local master
// Fast-forwarded master by 2 commits
```

Now our tree looks like this:

```
             (C3)
            /    ^ HEAD,ISS:1
(C1) -> (C2) 
             \
               (C4) -> (C5)
                           ^ MASTER
```

This can be a confusing situation & there are three ways to merge ISS:1 into Master.

1. Create a merge commit - Probably the most common scenario
2. Create a squash commit
3. Rebase ISS:1 commits on top of Master

### Merge Commits

Most commits have one parent. Merge commits **have two parents** thus tailoring all the commits from one branch into another. This is the default behavior of the merge command when a branch has diverged from the other. Let's go back to our example:

```
             (C3)
            /    ^ ISS:1
(C1) -> (C2) -> (C4) -> (C5)
                            ^ Master
```

#### No Merge Conflicts

This is the workflow when Git can do the merge without the need for human intervention.

```
$ git stash/commit # Finish changes on ISS:1
$ git checkout master
$ git merge ISS:1 
// Merge commit created on Master
```

Our tree after the merge looks like this:

```
              --------> (C3) ----
            /            ^ISS:1   \
(C1) -> (C2) -> (C4) -> (C5) ------ > (C6)
                                          ^ Master
```

Success! C6 now combines the changes of ISS:1 & Master. It is the resulting merge commit since it has two parents (C3 & C5).&#x20;

#### Merge Conflicts

Often times, merge conflicts can arise if master & ISS:1 have differing changes in identical regions of a file. Human intervention is needed in this case. Git leaves the working directory in a limbo state awaiting you to resolve the commit. Let's go back to our example:

```
             (C3)
            /    ^ ISS:1
(C1) -> (C2) -> (C4) -> (C5)
                            ^ Master
```

```
$ git stash/commit # Finish changes on ISS:1
$ git checkout master
$ git merge ISS:1 
// Error! Conflicts were detected. Resolve changes and commit to continue...
```

We don't generally want to commit anything onto our Master branch or play around with things until we are exactly sure of what we are doing. *Thus,* *we importantly resolve the commits on our ISS:1 branch as opposed to the Master branch.*

Let's change back to the ISS:1 branch.

```
$ git checkout ISS:1
$ vim index.js # Fix the conflicts
$ git add *; git commit -m 'Fixed conflicts'
// Fixed Conflicts is a merge commit
```

Our git tree looks like this now!

```
             (C3) ------------- > (C6)
            /                 /       ^ISS:1
(C1) -> (C2) -> (C4) -> (C5)
                            ^ Master
```

But our goal was to merge master but it is still behind ISS:1. We want to move the Master pointer to C6. We can now do this since C6 is a child of C5. Merging ISS:1 into Master is now a simple affair.

```
$ git checkout master
$ git merge ISS:1
// Fast forward Master by one commit
```

```
             (C3) ------------- > (C6)
            /                 /       ^ISS:1, Master
(C1) -> (C2) -> (C4) -> (C5)
```

#### Pull Requests

PRs are a Github feature that let other developers review the changes from a feature before it goes into the production branch. PRs are also a good way to enforce a consistent, controlled access point for changes to the production branch. For example, only a select few members of the organization may have permission to merge branches into the production branch.

#### Cannot Merge Automatically

When you create a PR that will result in merge conflicts, the PR will say 'Cannot Merge Automatically'. To resolve this, we let local/master be even with origin/master and then merge master into ISS:1 creating the merge commit on ISS:1.&#x20;

{% code title="" %}

```
             (C3)
            /    ^ ISS:1
(C1) -> (C2) -> (C4) -> (C5)
                   ^ master ^ origin/master
```

{% endcode %}

```
$ git fetch origin master
$ git checkout master
$ git merge origin/master
```

Out git tree now looks like this:

{% code title="" %}

```
             (C3)
            /    ^ ISS:1
(C1) -> (C2) -> (C4) -> (C5)
                           ^ master, origin/master
```

{% endcode %}

Let's merge master into ISS:1

```
$ git checkout ISS:1
$ git stash/commit # Clean your changes
$ git merge master # Merging master into ISS:1
// Merge Conflicts!!!
$ vim index.js # Resolve conflicts
$ git add *; git commit -m 'Resolved Conflicts'
$ git push origin ISS:1 # Pushed changes to origin
```

Our local repo now looks like this:

{% code title="" %}

```
             (C3) ------------- > (C6)
            /                 /       ^ISS:1
(C1) -> (C2) -> (C4) -> (C5)
                            ^ master, origin/master
```

{% endcode %}

If we use the PR button to merge, Github will make a new commit on our master branch. This is because PRs are configured to make an explicit merge commit as opposed to doing a simple fast-forward even when this is possible (as is the case in this situation).

After clicking merge button on the PR:

{% code title="" %}

```
             (C3) ------------- > (C6) -------------
            /                 /       ^ISS:1         \
(C1) -> (C2) -> (C4) -> (C5)--------------------------- > (C7)
                            ^ master                          ^ origin/master
```

{% endcode %}

This was a little confusing to me as C6 & C7 would represent identical snapshots of the repository.
