32

Even when my feature branch was branched out from the latest version of main, when I attempt to rebase my PR (from feature X to main), I end up seeing:

This branch cannot be rebased due to conflicts Rebasing the commits of this branch on top of the base branch cannot be performed automatically due to conflicts encountered while reapplying the individual commits from the head branch.

I understand that this can be resolved by:

git checkout main
git rebase feature/x
(resolve conflicts)

However, direct pushing to main is locked and I need to go through a PR. What are the steps to successfully be able to rebase a feature/x branch to main through a pull request?

Drew
  • 6,311
  • 4
  • 44
  • 44
Jay
  • 4,873
  • 7
  • 72
  • 137

5 Answers5

39

If you created the branch from main but you now need to rebase onto main then main must have been updated since you created your branch. The conflicts come from those changes.

I understand that this can be resolved by:

git checkout main
git rebase feature/x
(resolve conflicts)

This isn't correct. This would rebase main onto feature/x; you need to rebase feature/x onto main.

Instead,

  1. update your local main from GitHub before the rebase by pulling it or similar,
  2. check feature/x out,
  3. run git rebase main, and
  4. resolve conflicts.

Then push your feature branch to GitHub (you'll need to use --force-with-lease since this rewrites commit hashes). The pull request will be updated accordingly.

Drew
  • 6,311
  • 4
  • 44
  • 44
ChrisGPT was on strike
  • 127,765
  • 105
  • 273
  • 257
  • 3
    The mention of `--force-with-lease` earns you an upvote. – jub0bs Apr 25 '18 at 00:43
  • After step 4 above: 5. You may have to do: `git rebase --continue` don't commit, then you can finally push using `--force-with-lease` as mention above. – Lekia Jun 07 '21 at 09:25
21

First let's look at what is causing this problem, from the question:

This branch cannot be rebased due to conflicts Rebasing the commits of this branch on top of the base branch cannot be performed automatically due to conflicts encountered while reapplying the individual commits from the head branch.

This occurs when it's not possible to rebase each individual commit onto main cleanly.

If, for example, a PR had merge conflicts and they were solved by merging main and fixing the conflicts in a new commit that will have no effect on this warning as it will not allow GitHub to rebase the PR cleanly.

Note that all solutions involve rewriting history for the PR branch and merging via GitHub's UI.

Fix using git rebase

If you wish to keep all individual commits:

$ cd /my/repo
$ git checkout my-feature-branch
$ git fetch
$ git rebase origin/main             # 1
$ git push -f origin/my-feature-branch # 2

This will:

  1. Rebase (Reapply) each commit in the PR on top of main
  2. Update the PR branch on GitHub

If a PR has a none-trivial number of commits this can be a painful process to go through - there will definitely be at least one merge-conflict to resolve (otherwise, GitHub wouldn't have the warning on the PR (: ) - if you start this process and decide it's the wrong move git rebase --abort to get back to a clean working copy.

Fix using git rebase -i

If you wish to keep all/most individual commits with tweaks:

$ cd /my/repo
$ git checkout my-feature-branch
$ git fetch
$ git rebase origin/main -i          # 1
$ git push -f origin/my-feature-branch # 2

This will:

  1. Rebase each commit in the PR on top of main interactively
  2. Update the PR branch on GitHub

This can be handy if for example you recognise that by squashing a few commits together, or reordering commits, or etc. a clean history can be obtained.

Again, if you start this process and decide it's the wrong move (or want to try again) git rebase --abort to get back to a clean working copy.

Fix using git reset

If you don't care for keeping the individual PR commits, there is a simpler/easier option:

$ cd /my/repo
$ git checkout my-feature-branch
$ git fetch
$ git merge origin/main                # 1
$ git reset --soft origin/main         # 2
$ git commit -va                       # 3
$ git push -f origin/my-feature-branch # 4

This will:

  1. Make sure that the branch is up to date with origin/main
  2. Reset the local branch to match origin/main (but leaving the working copy unmodified)
  3. Create a new single commit for the PR (this is a new commit, remember to write a detailed commit message!)
  4. Update the PR branch on GitHub

This process will not require you to resolve intermediary conflicts.

Avoiding in the future

Github allows multiple merge strategies for PRs:

enter image description here

The problem in the question is specific only to rebase and merge, so to avoid: Just don't use/force rebase and merge strategy.

Drew
  • 6,311
  • 4
  • 44
  • 44
AD7six
  • 63,116
  • 12
  • 91
  • 123
1

If you have landed here while using GitHub online/web, there may be an faster and easier solution for you:

If you have:

  1. Raised a PR (Pull request) in the usual way,
  2. Had it approved, but
  3. You are looking at a message that says "This branch cannot be rebased due to conflicts", not the usual green button to merge. There is no green merge button like there usually is.
  4. If your default merge setting is to rebase, not to squash.

It's not obvious, but you can click on the GIT message (just next to it) in the UI and it will reveal the other merge types (green buttons).

You can choose to squash which will lose the individual commits you have made so far, but this will get your PR into the repo.

CyclingDave
  • 1,150
  • 1
  • 10
  • 22
0

Just close and reopen the pull request. It worked for me

Venky
  • 51
  • 2
  • 8
  • Thank you! I came here having gotten that message one a PR that's already up to date with master (2 commits ahead, 0 behind) with 18 lines changed (and no, not super-long lines, either). So, advice about how to rebase isn't particularly helpful. Neither is changing merge strategies - there are good reasons why one might need to use the rebase and merge strategy (branch requires linear history, but you want to retain separation between logically separate parts of your PR). – Adam Azarchs Jul 21 '23 at 10:40
-3

Steps to do rebase :

x@xyz-pc:~/workspace$ git branch

  • xyzBranch

    main

x@xyz-pc:~/workspace$ git checkout main

Switched to branch 'main'

Your branch is up-to-date with 'origin/main'.

x@xyz-pc:~/workspace$ git branch

  • main

    xyzBranch

x@xyz-pc:~/workspace$ git pull

Updating ...... Fast-forward ....

x@xyz-pc:~/workspace$ git pull

Already up-to-date.

x@xyz-pc:~/workspace$ git checkout xyzBranch

Switched to branch 'xyzBranch'

x@xyz-pc:~/workspace$ git branch

  • xyzBranch

    main

x@xyz-pc:~/workspace$ git rebase main

First, rewinding head to replay your work on top of it...

Fast-forwarded xyzBranch to main.

Conflict scenario :

x@xyz-pc:~/workspace$ git rebase main

  • If there is no conflict, then rebase is successfull and updated message will be displayed.

  • If you see an error you will need to resolve the conflicts, so 'git status' will display the conflicted file like below :

x@xyz-pc:~/workspace$ git status

rebase in progress; ..... Unmerged paths:

    both modified:   conflicting-file

It will show you the conflict file under unmerged paths.

Resolve that file and commit and do 'git rebase --continue'

Drew
  • 6,311
  • 4
  • 44
  • 44
kavita
  • 417
  • 4
  • 8