DEV Community

Cover image for Tweaking commits with Git's Magic Time Machine✨, aka git rebase
Lucas G. Terracino
Lucas G. Terracino

Posted on

Tweaking commits with Git's Magic Time Machine✨, aka git rebase

Magic is everywhere! Specially in your terminal, and our git has some of its own. In this post I'm going to show you a little of this magic that lives inside the git rebase command.
🐻 Bear in mind, this post assumes you are already familiar with git.

git rebase

📖 Reapply commits on top of another base tip.

This sounds and looks just like git merge... right?

git checkout feature
git rebase master
Enter fullscreen mode Exit fullscreen mode

Not quite. git rebase, moves the branch and incorporates all of the new commits, but re-writing the project history by creating brand new commits for each commit in the original branch.

These brand new commits thingy thing, brings up the golden rule of rebase: do not rebase on public branches.

Besides rewriting commits, we can add two other key features of git rebase:

  • Doesn't make new commits (because it rewrites them)
  • Can be used in the same branch we are working on

This three key features gives us the opportunity to tweak our commits, which comes really in handy when

  • we messed up with the commit message
  • made a very tiny file change and its commit would be better off inside a larger one
  • when we need to change the order of the commits
  • remove a whole commit

Getting our hands dirty

Graph of a git branch with four commits

Let's say I've been working on this new feature branch, and 4 commits in, I want to make some changes to them using rebase.

git rebase -i HEAD~4
Enter fullscreen mode Exit fullscreen mode
  • git rebase: calls, of course, the git-rebase command
  • -i: Shorthand for interactive, this makes a list of the commits that we are about to rebase, letting us edit that list and how we are going to rebase them. This file is where we are going to do today's magic.
  • HEAD~4: The tilde is used to point to a position relative to a specific commit, in this case, the HEAD; giving us its 4th parent.

Now, a file has been opened on your designed IDE called git-rebase-todo and we are ready to do some magic with out git project.

# git-rebase-todo
pick 4acdb1d First Commit of Feature
fixup be76710 Second Commit of Feature
drop 78acdd0 Third Commit of Feature
reword 9480b3d Fourth Commit of Feature
Enter fullscreen mode Exit fullscreen mode

When we use --interactive/-i this file is going to tell git what to do with each of the commits listed. The list can be re-ordered and git will execute your orders from top to bottom!

Graph of a git branch with commits being reordered via git rebase

By default, all commits come with the option pick, but there are many options we can use to alter our commits.
Let's see what that means and what we can do with the other commands rebase has for us.

pick

Pick signals git to use the commit, this means, it will keep this commit and use it in its rebasing.
When should I use pick? Every time we want to keep a commit!

pick be76710 Super awesome commit message
# You can also use the short version: p
p be76710 Super awesome commit message
Enter fullscreen mode Exit fullscreen mode

reword

Reword signals git to use the commit just like pick but lets us change the commit message when it's about to be commited again. This option will prompt you with a file to edit with the previous commit message for you to edit.
When should I use reword? Every time we want to keep a commit, but we need to make changes to it.

reword be76710 Super awesome commit message
# You can also use the short version: r
r be76710 Super awesome commit message
Enter fullscreen mode Exit fullscreen mode

edit

Edit signals git to use the commit, but stops just before commiting to let us make changes or adjustments. This amendments to the code are not limited at all. Everything will be included in the commit long as you stage them: this includes typos, a few more lines of code, or a whole new file.
When should I use edit? Every time we want to keep a commit, but we need to slip in a few more changes to it.

edit be76710 Super awesome commit message
# You can also use the short version: e
e be76710 Super awesome commit message
Enter fullscreen mode Exit fullscreen mode

squash

Squash signals git to merge the commit with the previous one, this means, both commits will become one with a new hash. Git will let you reword the commit message of this newly created commit and will prompt you with a file to edit it.
When should I use squash? Every time we want you want to meld one or more commits with a previous one.

squash be76710 Super awesome commit message
# You can also use the short version: s
s sbe76710 Super awesome commit message

Enter fullscreen mode Exit fullscreen mode

fixup

Fixup signals git to merge the commit with the previous one, just like squash but discarding the commit's message.
When should I use fixup? Every time we wan to meld one or more commits with a previous one disregarding its message is.

pick 4acdb1d Super Awesome Commit
fixup be76710 This commit is going to be merged with the one on top of it
pick 9480b3d Another Super Awesome Commit
# You can also use the short version: f
f be76710 Super awesome commit message
Enter fullscreen mode Exit fullscreen mode

Graph of a git branch with a commit being merged with the previous one via git rebase and fixup

drop

Drop signals git to remove the whole commit.
When should I use fixup? Every time you want to discard all the changes made by a commit.

drop be76710 Super awesome commit message
# You can also use the short version: d
d be76710 Super awesome commit message
Enter fullscreen mode Exit fullscreen mode

So, again, how do I use this magic tricks?

You've just commited a very big change to your new website index.html. Your eyes wonder upon the job done, and suddenly, a nasty typo appears out of nowhere.

✨ Just make another commit with the fixed typo. Invoke the magic words on your terminal git -i rebase HEAD~2 and then, use fixup to merge the commit done for the typo.

After making three commits, you've noticed the first one has a commit message that others in your team would find confusing.

✨ Just call upon the greatness of rebase with git rebase -i HEAD~3 and use reword on the commit you'd like to change its message.

You have noticed the whole commit you've done, five commits ago is wrong, but... there are many commits you don't want to lose using reset!

✨ Rebase comes to hide all of those silly mistakes! Let's recite together on our terminal git rebase -i HEAD~5 and using drop that commit is now gone forever!

With great power comes great responsibility

Before using rebase, you have to make sure if at any point, the commits you are going to merge have already been merged to public branch, if that's the case... don't us rebase. Remember what we've learned about rebase making new commits? You'll have issues because we've just rewritten the commits history!
Another thing to keep in mind is, when we rebase, all the commits are applied one after the other, this means, dropping or changing the order of any commit might pop up conflicts you'll have to fix and then commit before rebase can continue. After you've successfully dealt with them, gracefully resume your rebase with git rebase --continue. Or just go with git rebase --abort and cry yourself to sleep remembering those conflicts... oh lord... those conflicts.

📚 Let's read more!

That's it from me for now, I hope you find it useful and on your next project less of these pesky typos plague your commit history, thanks to the magic of rebase

Top comments (2)

Collapse
 
jessekphillips profile image
Jesse Phillips

Nice, I tried my explanation as describing it in terms of scripting.

Collapse
 
nomade55 profile image
Lucas G. Terracino

I've added your post to the bottom links since I think your explanation goes slightly more in depth. Good post!