Git: different types of merging

This walkthrough will compare the results of different types of merging

Our initial state is: we are on wip branch, ahead of master by 3 commits:

$ git log --oneline --graph --all
* 73ba012 (HEAD -> wip) edit file2 at 12:59
* 542198c edit file2 at 12:58
* d555619 add file2 at 12:57
* 919c27f (master) edited notes at 10:41
* 7fe6713 edited notes at 10:41
* ebfca7d initial

Use case 1: simple merge

We switch to master branch and list the commits

$ git checkout master
    Switched to branch 'master'
$ git log --oneline --graph
    * 919c27f (HEAD -> master) edited notes at 10:41
    * 7fe6713 edited notes at 10:41
    * ebfca7d initial

Now we tell Git to merge wip onto master

$ git merge wip
    Updating 919c27f..73ba012
    Fast-forward
     file2.txt | 6 ++++++
     1 file changed, 6 insertions(+)
     create mode 100644 file2.txt
$ git status
    On branch master
    nothing to commit, working tree clean

Here’s our graph of commits after the merge – the master branch gained 3 fresh commits: d555619, 542198c, 73ba012

    $ git log --oneline --graph
    * 73ba012 (HEAD -> master, wip) edit file2 at 12:59
    * 542198c edit file2 at 12:58
    * d555619 add file2 at 12:57
    * 919c27f edited notes at 10:41
    * 7fe6713 edited notes at 10:41
    * ebfca7d initial

Use case 2: squash merge

Again, we switch to master and then issue merge command, but this time with –squash option

$ git checkout master
Switched to branch 'master'

$ git merge --squash --verbose wip
    Updating 919c27f..73ba012
    Fast-forward
    Squash commit -- not updating HEAD
     file2.txt | 6 ++++++
     1 file changed, 6 insertions(+)
     create mode 100644 file2.txt

At this point Git has’t committed our merge:

$ git log --oneline --graph
    * 919c27f (HEAD -> master) edited notes at 10:41
    * 7fe6713 edited notes at 10:41
    * ebfca7d initial

but it did squash all 3 commits from wip branch into a single edit:

/repo1 (master)
$ git status
    On branch master
    Changes to be committed:
      (use "git reset HEAD <file>..." to unstage)
            new file:   file2.txt

now we commit this merge:

$ git commit -m "single commit from a squashed wip merge"
    [master e82cd25] single commit from a squashed merge
     1 file changed, 6 insertions(+)
     create mode 100644 file2.txt

$ git status
    On branch master
    nothing to commit, working tree clean

We get clean history without any intermediate commits

$ git log --oneline --graph
    * e82cd25 (HEAD -> master) single commit from a squashed wip merge
    * 919c27f edited notes at 10:41
    * 7fe6713 edited notes at 10:41
    * ebfca7d initial

and the wip branch shows 3 commits.

$ git log --oneline --graph --all
    * e82cd25 (HEAD -> master) single commit from a squashed merge
    | * 73ba012 (wip) edit file2 at 12:59
    | * 542198c edit file2 at 12:58
    | * d555619 add file2 at 12:57
    |/
    * 919c27f edited notes at 10:41
    * 7fe6713 edited notes at 10:41
    * ebfca7d initial

We could delete the wip branch now as it’s no longer needed

$ git branch -D wip
    Deleted branch wip (was 73ba012).

$ git log --oneline --graph --all
* e82cd25 (HEAD -> master) single commit from a squashed merge
* 919c27f edited notes at 10:41
* 7fe6713 edited notes at 10:41
* ebfca7d initial

The opposite Scenario: merging feature onto master, and we want clean fast-forward commit history without merge commits.

We use “git merge –ff-only” for this

/ansible_cna (master)
$ git merge --ff-only wip
Updating 8f89635..969a396
Fast-forward
 files/scripts/healthcheck-cna.yml | 64 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)
 create mode 100644 files/scripts/healthcheck-cna.yml

Now push to remote

/ansible_cna (master)
$ git push
   8f89635..969a396  master -> master

Now delete our temporary feature branch (wip)

$ git branch -d wip
Deleted branch wip (was 969a396).

And we push deletion to remote

/ansible_cna (master)
$ git push origin --delete wip
 - [deleted]         wip