When to do git merging or rebasing

2012-04-03 by Senko Rašić

This one pops up fairly often, and can indeed be quite confusing – when to use merge versus rebase in git? Here’s the answer.

In merge, you combine two divergent branches back into one. There’s also a special kind of merge called fast-forward, done when a branch being merged is just a continuation of the branch you’re merging into – so the new commits are just pasted on top of the target branch (ie. it is “fast-forwarded”).

In rebase, you change your branch (that’s being rebased) so it looks like it was branched off a new base, not the original one. This involves rewriting the commits, so you’ll end up with different commit IDs.

So, when to use either? The rules are suprisingly simple:

Never rebase public branches

By “public branches” here I mean branches that other people might have checked out. Rebasing rewrites history, and anyone having branches that were checked out of the history you just unmade will be sad, angry or worse. That’s one reason you can’t just push rebased branch on GitHub (unless you force it and sacrifice a kitten). So just say no.

Rebasing private branches is perfectly fine, and in fact often done when squashing or rearranging commits, cleaning up a branch before going public with it, or just updating long-running feature branch (go easy on the last one, though).

Never merge upstream master into your master

By “merge” here I mean a recursive (non-fast-forward) merge, ie. the one that leaves tracks. And the rule is not only for master, but for any upstream tracked branch you may want to merge back into one day.

As a rule of thumb, fork master should always be in sync with upstream master (ie. only do fast forward merges/pulls), only having the commits that are in upstream already. Also, you should never have to merge master (local or remote) into a feature branch. If you need to update an existing feature branch, rebase it rather than merging into int.

Updating public feature branches

What to do if your public branch needs to be updated from upstream? You can’t rebase it since it’s public, and you can’t merge into it since you’ll want to merge it back some day.

Turns out it’s really simple: create a fresh one off of upstream, merge your branch into it, and continue working on a new one.

(This was originally a comment on the How To GitHub: A Complete Guide to Forking, Branching, Squashing and Pulls article Hacker News discussion. The article itself and the ensuing discussions are full of useful advice – if you haven’t already, go read them!)

Author
Senko Rašić
We’re small, experienced and passionate team of web developers, doing custom app development and web consulting.