Git Merge and Rebase

Introduction

This page contains a quick reference to merge and rebase in Git. This is part 4 of the Git quick reference series.

Merging

This is the command to merge changes from a branch into the current branch:

By default, git merge  commits the merge.  To use a commit message instead of the default message, use the -m  flag:

If you do a git merge and forgot to provide a message, you can always amend the last commit message with:

To stop the commit, you need to use the --no-commit flag :

Fast Forward Merge

Git uses a Fast Forward merge when the current branch head is a direct ancestor of the branch being merged. With the fast forward merge, the head of the current branch is just rolled over to the head of the merged branch. As the head is just moved, there is no need to create a merge commit.

Git Merge Fast-Forward Strategy
Git Merge Fast-Forward Strategy

Recursive Merge

Git uses a recursive merge when the current branch head diverges from the branch being merged.  In other words, both branches have a common ancestor (commit A below), but both branches have since moved on (commits B and C). The recursive merge performs a three-way merge. The result is a merge commit (commit D below) pointing at both branches.

Git Merger Recursive Strategy
Git Merger Recursive Strategy

Rebasing

There are two ways to integrate changes from one branch to another: merge and rebase. Rebase takes a series of commits from a branch, and replays them on top of another branch. While the contents of the rebased commits are the same, the parents are different. This implies the SHA-1 of the rebased commits will be different from the original, thus being considered a different commit.

Git Rebase
Git Rebase

The log history of a rebased branch is clearer as it appears to be linear.  Rebasing is useful when you work in a feature branch and want to integrate your work into the master branch maintaining your commit history.

As a rule of thumb, however, we should only rebase local commits. That is, we should not rebase commits that have been shared with another developer. The issue with rebasing is that it creates a commit that are similar but different. This can lead to many merge conflicts.

Rebase your current branch commits onto master

We first rebase the changes from the feature branch into master.

The above just commits the rebased commits into master, but does not advance the head. To complete the integration, we need to merge to fast-forward the head.

Rebase against a tag or commit ID

Undo a rebase

Pushing feature branch after Rebase

If you rebase a feature branch that tracks a remote branch, you will need to force push.

git push  will refuse to update a remote branch if the local change being pushed is not an ancestor of the remote branch. This is the case after rebasing a branch.

Imagine you have the following scenario.

When you rebase the feature branch onto master, changes e , f  and g  are replaced on top of commit d  in master.

At this point, the head of the local feature branch ( g' ) is no longer a direct ancestor of its remote branch ( g ).

If you now try to push, you will get this error:

This is resolved with a force push:

Bibliography

  • Git Reference: http://git-scm.com/doc
  • Pro Git. Scott Chanon and Ben Straub. APress. http://git-scm.com/book/en/v2
  • Pragmatic Guide to Git. Travis Swicegood. Pragmatic Bookshelf, 2010.
  • Version Control with Git. Jon Loeliger and Mattew McCullough. O’Reilly, 2012

Git Tools

The following two tabs change content below.

Eduard Manas

Eduard is a senior IT consultant with over 15 years in the financial sector. He is an experienced developer in Java, C#, Python, Wordpress, Tibco EMS/RV, Oracle, Sybase and MySQL.Outside of work, he likes spending time with family, friends, and watching football.

Latest posts by Eduard Manas (see all)

Leave a Reply