This is part 2 of my serie on How I Git it. You can read Part 1 here.
Rebase is such a great tool to get my commits just right. Basically, it’s this process that let’s me rewind back to a commit of my choosing, and then replay all the commits, one at a time, allowing me to:
- Change the order of the commits.
- Drop a commit.
- Change a commit message.
- Combine one or more commits into one (squash them).
- Pause the replay, and make changes to a commit.
- Pause the replay, and make a new commit in the middle of the commit graph.
- Pause the replay, and split a commit into two or more commits.
- Fuck up, abort and try again.
- Pull in new commits from another branch (e.g. develop), and put my commits on top of the new ones.
- Solve merge conflicts like they never happened.
So many uses! Stick with me and I’ll show you how.
Change the order of the commits⌗
I select the commit that I want as the starting point, and I choose to rebase interactively.
Or “git rebase head~3 –interactive” in the command line
In interactive mode, this dialog will pop up that shows me which commits will be replayed, and in what order, starting from the top.
Changing the order is only a matter of re-arranging the lines (Ctrl-X, Ctrl-V).
I hit Save (Ctrl-S), close the dialog and then the rebase process starts. When done the order has changed.
Drop a commit⌗
Maybe I changed my mind and didn’t want those example git commands. Let’s remove them.
As the help text in the interactive rebase dialog says, dropping a commit is only a matter of changing “pick” to “drop” (or “d"):
Or you can just remove the whole line, that’s what I usually do (Ctrl-X)
Afterwards, that commit will be gone:
Change a commit message⌗
There’s two approaches that I use for this, depending on the situation.
First approach, if part of an interactive rebase where I’m also doing other stuff, then it’s easy to use the “reword” (or “r") operation in the interactive rebase dialog:
A text editor will appear and this time I can edit my commit message:
Afterwards, the commit has been changed:
The second approach is probably the one I use more often:
After that the same text editor will pop open. Edit, Save, Close and the commit message will then be changed.
Combine one or more commits into one (Squash)⌗
I love this one, and it’s something I do a lot. Literally many times a day. For instance, if I refactor some code that I had committed earlier that day, then I want the refactored code to be part of that earlier commit.
One of my reasons for doing so, is that a potential code reviewer doesn’t have to waste brain cells on understanding code that will be changed in a later commit anyways.
Other typical real world examples of commits that could have been squashed:
- Forgot to add image.
- Fix typo in variable.
- Fix failing tests.
- Fix failing build.
- Forgot to handle edge cases.
- Initial attempt too slooow… this should do the trick.
Point being, why show the world my mistakes when I can make it so they never happened in the first place? (also, I prefer not knowing how your sausages are made).
Let’s say I committed some additional text, but I figure it rather belongs in an earlier commit:
I initiate interactive rebase like usual, and I select either squash or fixup.
The squash option let’s you combine the commit messages, while fixup will keep only the first commit’s message.
Now the trick is to move the commit that I want to squash beneath the commit that I want to squash it into.
After saving and closing the dialog, the text editor will appear again and I can modify the commit message so that it takes into account the latest additions:
Edit, Save and Close the dialog to complete the rebase process.
If I had chosen the fixup operation I would not have gotten the opportunity to edit the commit message. Instead, only the first commit message would have been used. Fixup is what I use most of the times though.
I can, and often do, squash several commits into one commit as part of the same rebase process. It’s all just a matter of arranging the commits and choosing squash or fixup.
Getting comfortable with the git interactive rebase process is essential to How I Git it. Next up in is even More Rebase!