Interactive rebases are slower than non-interactive rebases.

$ git rebase -i origin/master

When you do an interactive rebase relative to another branch, an editor opens in which you can see all of the commits unique to the current branch. Once you close this editor, the rebase commences with a counter showing how many commits are left to process, which looks like this:

$ Rebasing (3/32)

For reasons I can only guess, going through these commits takes considerably longer than if you perform the rebase without the -i flag.1

Lately I have needed to frequently rebase a branch that has dozens of commits in it, containing thousands of lines of changes. Often I will be in this branch, make a change, commit it with a descriptive message, then discover one or two other lines of code that need to be changed and that logically belong to this commit. The natural thing to do is to make the change, create a quick bogus commit, and then do an interactive rebase so I can perform a fixup on that bogus commit, thus welding the two into the commit with the descriptive message.

If, after making these commits and before performing the interactive rebase, I were to run git fetch origin so as to grab the latest from the remote git server, I would have to sit back and patiently wait a good 10-15 seconds while the above-mentioned counter ran its course. Recently I’ve discovered that a much faster way to handle this is to perform the interactive rebase first, then fetch the origin, and then finally do a second non-interactive rebase.

$ git rebase -i origin/master
# handle my fixups and whatnot, and then:
$ git fetch origin
$ git rebase origin/master

Why is this faster than just doing a single interactive commit after fetching the origin? Well assuming when we start the above commands that the current branch is not behind the local history of the branch from which it was derived, the first rebase will not have its counter start at the first commit. It will instead start at the first commit that was modified in the interactive editor. In other words, if the branch had 32 commits and we changed the last commit to fixup, then the counter will start at 32. The interactive rebase will take 3% of the amount of time that it would take otherwise. Then the second non-interactive rebase will perform at machine gun speed.

There’s no reason to sit through a painstaking interactive rebase of an entire branch’s history, unless you actually need to modify a commit that’s at the beginning of that branch’s history.

  1. My best guess is that it’s because the interactive version scans each line of the interactive editor. Git has no idea what kind of reordering and monkeying you’ve done to that file and consequently it has to validate every aspect of it. Parsing the line would be very fast, but mapping the 7-character short commit hash on each line to a corresponding valid commit could take a few hundred milliseconds. In a branch that has 30 commits and thousands of lines of changed code, that could add up quickly. ↩︎