Understanding Rebase (And Merge) in Git
Table of Contents
While merging is definitely the easiest and most common way to integrate changes in Git, it's not the only one: "Rebase" is an alternative (and slightly advanced) means of integration.
The Case Against Merge Commits
A normal commit, carefully created by a human being, is a meaningful unit: it wraps only related changes and annotates them with a comment.
All this gets lost in a merge commit: it's created automatically by Git to cram in all the differing changes. It has no semantic meaning, no separation of topics. Of course, the contents of those individual commits are preserved. But the history - commented and nicely separated into individual, meaningful commits - that lead to this point is not preserved in a merge commit.
This is why some people dislike merging and instead use rebase.
The Beauty of Rebase
Instead of cramming all changes into a merge commit, a rebase preserves the original commits. The project's history then looks as if it had evolved in a single, straight line. No indication remains that it had been split into multiple branches at some point.
Let's walk through a rebase operation step by step. The scenario is simple: we want to integrate the changes from branch-B into branch-A, using rebase.
The command for this is very easy:
$ git rebase branch-B
First, Git will "undo" all commits on branch-A that happened after the lines began to branch out (after the common ancestor commit). Of course, it won't discard them but rather save them away, temporarily.
Next, it applies the commits from branch-B that we want to integrate. At this point, both branches look exactly the same.
In the final step, the new commits on branch-A are now reapplied - but on a new position, on top of the integrated commits from branch-B (they are re-based).
The result looks like development had happened in a straight line. Instead of a merge commit that contains all the combined changes, the original commit structure was preserved.
In case you're using the Tower Git client, you can use rebase simply by dragging the to-be-integrated branch and dropping it on the target branch, with the ALT key pressed. That's it!