Git Rebase Demystified- Explained for Beginners

Jul 1st, 2019

tutorial

If you're like me, you're a fan of "trunk based" git repos with lots of small branches for individual features. This is a great way to work, but if you use traditional merges, soon there are hundreds of irrelevant merge commits in the main branch.

While at first rebase can seem daunting, it's a great way to "merge" in changes from small feature branches. It's also easy to use, even if you're new to git!

This is a quick tutorial covering rebase that I hope you'll find helpful!

Photo by Trevor Wilson on Unsplash

What the Heck is a Rebase, Anyways?

While a traditional merge of a branch pushes changes into another branch with a merge commit, a rebase actually reapplies the commits on top of a different branch.

This might sound convoluted, but think of it as changing whenever you checked out from master to how master looks now. All your changes in your development branch get applied on top of the current HEAD in master. It's almost like rewriting history!

You also do not need to use --force when pushing, even though you are rewriting history. More on that in a minute.

So How Do I Rebase?

You don't have to do anything fancy to use rebase- your regular branch-based workflow will be just fine!

git checkout -b my-branch
# Hack Hack Hack...
git commit -m "Added a slick new feature."

It's git as usual.

When your changes are ready to be merged, you rebase master into your development branch. Don't rebase your branch into master, that leads to nothing but frustration. 😉

# On my-branch, rebasing with master in interactive mode
git rebase -i master

This converts your branch to be based on the latest commit in master, which means you can merge into master with a fast forward merge (so no merge commit).

git checkout master
git merge --ff-only my-branch

A fast-forward merge is why you rebase your branch on top of the current master: if you went the opposite way, the history of the master branch would change. This breaks the repo for everyone else who's checked out anre requires a --force to push- not good at all.

And that's it! Congrats! Your git commit history is super clean. 🎉

There's Conflicts and Everything Is Backwards!

If your branch and master both change the same file, don't worry! You can resolve conflicts in a similar way to traditional merging.

Due to a quirk of how rebase works, it's important to know that --ours and --theirs are reversed when you use rebase this way. That is, --ours checks out from master, and --theirs checks out from your branch.

# Keeps changes in the development branch.
git checkout --theirs somefile.txt

# Keeps changes in master
git checkout --ours someotherfile.txt

It's counterintuitive, but easy to remember after you know what's going on!

That's It?

That's the basics! I hope that if you have never tried rebase before, you'll check it out now. Even if you don't adopt it for all your repositories, it is a handy trick for experimenting with features on other branches.

Plus Github has a "rebase and merge" button now, so really, it can't be that hard to use can it?

Thanks for reading! See you around!