Git Rebase: tips & tricks

Cynthia Erdos
4 min readSep 11, 2018

--

There are some tips and tricks I found about rebase overtime. They are quite simple and make life much easier as a developer. I will not go into the difference between rebase and merge as many people have already done so. I am going to assume you know the basics about rebase.

Your ‘pre-rebase’ code is safe

When I first used git rebase and got conflicts I was afraid to go ahead, as I thought after force push, my pre-rebase branch would be gone forever, so if I screwed up something, my mistake would be irreversible.

Gladly I was wrong.

When you do a rebase, it takes every commit one-by-one and applies the changes of each on the top of the target branch. Why is this important? Your original branch is still there, untouched. You can get the commit hash of the last commit in your pre-rebase branch from git reflog .

Once you have the hash of the last commit of your old branch, you can just

$ git branch new_branch_name commit_hash

to create a brand new branch out of it, which is exactly the pre-rebase branch.

This gave me the confidence to fully embrace git rebase and use it all the time.

Force push is bad

Whenever you give the command git push -f you’re basically instructing git to overwrite remote with whatever you have in local. It’s needless to say it’s a dangerous move and I’ve experienced this first hand. What if I told you there is a safe way to do force push?

$ git push --force-with-lease

The above command looks at the history of your local branch and checks if it includes the commit the remote ref is pointing to, if it does not, then it refuses to push the changes.

Imagine it as a force push which prevents you overwriting stuff, you don’t want to be overwritten. Cool little feature, and if you use oh-my-zsh then you can use the ggfl alias to force-with-lease, otherwise you can set one yourself. Awesome!

But what to do now that I’ve done a rebase and I can’t push my changes because force with lease is rejecting my push.

Surely not git pull

At least not in feature branches. The thing about a simple git pull that it goes against what we are trying to achieve with rebase.

When you do a simple git pull you basically give a command to git fetch and then git merge which merges remote into your local branch essentially polluting your tree.

But when you say git pull --rebase you are instructing git to do a fetch and then a rebase on remote: git fetch + git rebase .

You can take this command even forward: git pull --rebase origin/master , this will do a fetch and rebase upon remote master.

All-in-one.

Git Rerere

Sometimes we have to rebase a branch with lots of commits and with loads of changes usually comes lots of conflicts. Even worse when you are half way through a rebase and you have to abandon it for any reason and after you come back to your code, you will have to resolve all your conflicts again.

Git rerere solves this issue. It creates a preimage for all your conflicting files and records your resolution in a postimage file.

Then when you get the very same conflict again it will automatically solves the conflict, you don’t have to do anything.

When you encounter a conflict you will see the following in your terminal:

CONFLICT (content): Merge conflict in fileWithConflict.jsonRecorded preimage for 'fileWithConflict.js'

And when you resolve it and continue you will see this:

Recorded resolution for 'fileWithConflict.js'

More importantly when you get the very same conflict you will see this in the terminal:

CONFLICT (content): Merge conflict in fileWithConflict.jsResolved 'fileWithConflict.js' using previous resolution.

After auto resolve the file will be unstaged, therefore you can review that the resolution is correct. In case you resolved something incorrectly you can give the following command:

git rerere forget fileWithIncorrectResolution.js

This will tell git to delete the preimage and postimage of the conflict that it just auto resolved.

Downsides of git rerere

  1. If you resolve a conflict incorrectly git will remember and reapply the incorrect resolution should it reoccur. Solution: git rerere forget fileWithIncorrectResolution.js
  2. As a lot is going on in the terminal, it might not be straightforward that git auto resolves a conflict on its own. Solution: read the terminal ️🚀.

How to enable git rerere?

You can just simply enable it globally by giving the command below:

git config --global rerere.enabled 1

After this you can let git take care of the rest, but keep in mind what’s happening behind the scenes.

--

--