Pragmatism in the real world

The beginner's guide to rebasing your PR

You’ve successfully created a PR and it’s in the queue to be merged. A maintainer looks at the code and asks you to rebase your PR so that they can merge it.

Say what?

The maintainer means that there have been other code changes on the project since you branched which means that your branch cannot be merged without conflicts and they would like to you to sort this out.

These are the steps you should take.


Read the summary.

1. Update your target branch from upstream

I assume you already have an upstream repository as described in The beginner’s guide to contributing to a GitHub project. The target branch you want to update can be found at the top of the PR on the GitHub site.

For example:

Pr title

The target branch in this example is develop, though I see master a lot too.

$ git checkout develop
$ git pull upstream develop && git push origin develop

2. Rebase your branch

The next step is to change to your branch which is the other branch listed in the PR details (feature/validator-result-interface in this example) and then perform a rebase:

$ git checkout feature/validator-result-interface
$ git rebase develop

This will rewind all your commits on this branch and then replay them against the tip of the branch you are rebasing against.

As you have been asked to do this, you’ll get conflicts. Don’t panic!

$ git status will show you which files are in conflict. For each one, follow this process:

  1. Open in editor and search for “<<<<<<” (that’s 6 <) to find the conflict
  2. Inspect and fix so that you end up with the correct text. Remove the lines starting with <<<<<<, ====== and >>>>>>.
  3. Press find-next in your editor to find the next conflict in the file.
  4. Once all conflicts in the file have been fixed, exit your editor
  5. Add this file to the staging index: git add {filename}
  6. Repeat until git status shows that all conflicting files have been added to the index

Once all conflicting files are fixed you can continue the rebase:

$ git rebase --continue

3. Push your newly rebased branch to origin

Finally, all you need to do is push your branch back to origin. Note that this will require a force push and you’ve probably been told to never do such a thing. This is the one exception to that rule because the maintainer asked you to do it.

So go ahead:

$ git push -f origin {victim branch}

It’s a good idea to leave a comment on the PR that you’ve done the rebase and the PR is ready for re-review.

All done

To summarise the steps required:

  1. $ git checkout {target branch}
  2. $ git pull upstream {target branch} && git push origin {target branch}
  3. $ git checkout {victim branch}
  4. $ git rebase {target branch}
  5. Fix conficts and continue rebasing
  6. $ git push -f origin {victim branch}

That’s it. Being asked to rebase your PR isn’t scary or (usually) difficult as long as you pay attention to what you’re doing. However, if you’re not fully comfortable with git, then I recommend buying the Git Workbook and working through all the exercises.

12 thoughts on “The beginner's guide to rebasing your PR

  1. What's the difference between rebasing and merging an up to date master into my feature branch and merging conflicts?

    1. Dylan,

      The main difference is that the commit history looks different. Rebase essentially rolls up all the commits on your branch and then moves the branch to the tip of master and then replays all your commits. This means that it looks as if you created the branch from the tip of master. Merge will show that you created the branch earlier and then pulled in the changes later.

      In my experience, most projects do not mind which route you take, though some prefer rebase so that their commit history is cleaner.

  2. Hi Rob,

    Would the following not do the same?

    1. git checkout {victim branch}
    2. git pull –rebase origin {target branch}
    3. Fix conflicts and continue rebasing
    4. git push -f origin {victim branch}

  3. Never push with force without specifying a branch!

    `$ git push -f origin` will push ALL branches with force (which may not be what you want).
    `$ git push -f origin {victim branch}` will only push the `{victim branch}`

    1. Sebastiaan, This has not been true since git 2.0's simple push change.

      However, explicitness has value when you want to ensure you know what's happening!

Comments are closed.