rebase like a boss

Everyone who loves Git hopefully loves branching. However, there’s a problem
with branching: merging your work back in. Surprisingly enough, Git’s
inflexibility
makes this action quite simple. It’s my opinion that Git users should be
branching frequently, and rebasing them back into the mainline when ready.

Merges should be used only to denote when long lived branches (read: several
weeks, months) are brought into the mainline, or for some reason you want to
specifically denote when two histories were joined together. Rebasing as often
as possible means you keep the history graph as simple as possible. For example,
you may be seeing a lot of these if you’re only doing merges:

There’s a way around this: use git rebase! The action of rebasing is
conceptually simple: you’re playing a set of changes on top of another branch. I
like Travis
Swicegood’s
metaphor the best: rebase is like a meat cleaver. Given the right amount of
skill, you can slice and dice your commits the way you want. Here’s an example
of a feature branch we just had for Hoptoad:

So, as you can see, there’s been a fair amount of work in this branch across
several days and contributors. There’s also commits going on in other branches
as well, most notably our master branch (the far left one). Now, if I had done a
merge, we would have seen this:

git checkout master
git merge lighthouse_config

Our merge commit specifically denotes when we brought our work into master. This
is a perfectly acceptable way of bringing in our changes, but now we have these
two paths of history when we don’t necessarily need them. Especially for long
lived feature branches, this can start to become a mess in your history if you
have multiple features being developed in parallel.

Another issue is when you want to bring in the latest upstream changes to your
feature branch: you’ll get a lot of little merge commits. Rebasing blows away
those tiny merge commits that we used for when we wanted to sync up with the
master branch. So, this means that all you’re left with is the clean history of
what happened. The commits have been moved to on TOP of the master branch after
a git rebase master:

git checkout lighthouse_config
git rebase master

We could get even cleaner by squashing our commits, but I didn’t squash in this
situation since multiple people had worked on the feature. In general, this is a
great way to use Git as shown by Josh Susser’s fantastic agile story
branch
post. If I had squashed the
branch,
it would end up like this:

git checkout lighthouse_config
git rebase -i master

So the lesson here is to rebase whenever possible. It keeps the history clean,
and it’s just easier in general to understand when you’re looking at the log.
Use git pull --rebase when pulling down your latest changes, or just use git
fetch and git rebase as you see fit. Just remember the golden rule of
rebasing and you’ll be fine: NEVER rebase existing, pushed commits!