DEV Community

João
João

Posted on • Edited on

What to do when rebase goes wrong?

Git (and other DVCS such as Mercurial) makes branches much easier than the previous, non-distributed versions. It is also very powerful, but sometimes things can go really wrong. One common issue is using git rebase when a branch is outdated and points to an old commit from master. Older branches can lead to a lot of conflicts, making rebase a nightmare. The purpose of this blog post is to show you some ways you can save time and probably your sanity using rebase. This is a specific to a simple branch rebase that's often needed when the branch is based on a commit that's just too old.

The simplest solution is to just use git merge, but there are some reasons why you may not want to do that:

  • It pollutes the tree with merge commits. Depending on the number of commits, it can look quite messy. In my case, the repository constantly receives hundreds of commits in a single day.
  • If you're using Pull Requests or Phabricator diffs, using git merge is not recommended.

Suppose we have a feature branch. First, you need to the commit at master that started your branch. In the following image, it's C2

Alt Text

You can find it by using the git merge-base command:

$ git merge-base master feature
c2ff9421e78bd5e8f5d9c72702439f989e3f10e0

Now that we have the base commit for the branch, let's generate a patch for your branch:

$ git diff --patch c2ff9421e78..feature > feature.patch

Now that you have your patch for the whole branch, switch to master, retrieve the latest changes and create a new branch

$ git switch master
$ git pull
$ git checkout -b feature-rebase-temp

What we do now is just apply the patch. What difference does it make? Well, it will expose absolutely all conflicts right away, instead of complaining about at conflicts at each single commit of the feature branch:

$ patch -p1 --merge < feature.patch
... resolve all conflicts
$ git commit -m "Your message"

This branch is now corresponding to the post-rebase state of your feature branch. If you are okay with not having the commit history of your feature branch, you can just make the feature-temp branch your feature branch:

$ git branch -m feature feature-outdated
$ git branch -m feature-temp feature

You lose the previous history, but in my experience this is the safest route when your branch and master differ way too much, you don't risk losing changes and have all the conflicts at once.

Top comments (3)

Collapse
 
moopet profile image
Ben Sinclair

Also, git rebase --abort is your friend :)

Collapse
 
jingxue profile image
Jing Xue

Why not just do git merge master from the feature branch? You would end up doing the same amount of merging, if there are any conflicts, as patch --merge, but you'd be doing it with git merge's much more powerful merging capabilities (various merging strategies, options, git mergetool, etc.). And you'd have preserved all the history.

Collapse
 
joaomarcusc profile image
João

Good point! I updated the blog post with some reasons why one would not want to use git merge