A Pull Request was created on GitHub targeting the wrong branch (let’s call it old-branch). We needed to change the target to good-branch. However, because old-branch had already been merged into our feature branch, cherry-picking individual commits was difficult. Let’s call the branch where the Pull Request is open pr-branch.
Rework strategy
At work, some Pull Requests are merged using a merge commit, but I much prefer Squash merges, as it allows us to worry less about the Pull Request’s internal commit history.
With that in mind, the rework strategy was simple:
- identify the diff between the original target branch and the PR branch
- export those changes into a patch file
- reset the current PR branch to the new desired target branch
- apply the patch
- commit and force-push to update the Pull Request
- change the Pull Request’s target branch in the GitHub UI
By following this process, the Pull Request ends up with a single, clean commit containing all the original changes.
Commands
Here is the Git workflow to execute this rewrite:
- switch to the PR branch:
git switch pr-branch - reset the branch to the new target:
git reset --hard origin/good-branch(it will delete uncommitted changes) - generate a diff between the old target and the original PR state:
git diff origin/old-branch...origin/pr-branch > changes.patch(be careful of the 3 dots here to find the common ancestor between the two branches and start the diff from here) - apply the patch to the local branch:
git apply changes.patch(resolve any conflicts here) - stage the changes:
git add . - create a new commit:
git commit -m "feature description" - overwrite the remote branch:
git push --force - update the target branch: go to the Pull Request on GitHub and edit the base branch to
good-branch.
Using a Squash merge strategy provides more flexibility and makes manipulating Pull Requests much easier in scenarios like this.