Tenfour04 Tenfour04 - 3 months ago 9
Git Question

Fixing a mangled master branch in fork

I was working on a pull request for an open source project, but I accidentally committed my changes to my local

branch. Without thinking it over hard enough, I just went ahead and pushed it to my origin and submitted my master branch as a PR. Then I later pulled the upstream master into my master so I could fix merge conflicts to keep my PR up to date. Since then, more commits have been made to upstream.

So now I have:

upstream master: A - B - C ... H - I - J

my fork master: A - B - X - Y

Where X was the first version of my PR, and Y is a merge of C-H onto X.

So now my fork is in quite a tangle. I can't work on unrelated PRs without starting a branch before B and then pulling upstream master into that branch each time. And if my original PR is rejected or takes a year to get feedback on, I'll be stuck in this state indefinitely.

Are there any options for fixing this? Do I have to nuke my PR and my X and Y commits and redo them manually (and if so, how)? Or can I salvage my PR somehow and get my master branch back in sync with upstream?


What I would do in this scenario looks a bit like this:

First, check out a new branch from your existing master:

git checkout -b master-preserve

Then, reset your master to upstream/master:

git checkout master
git fetch upstream
git reset --hard upstream/master

Now, create another branch:

git checkout -b upstream-with-commits

And cherry-pick X and Y onto it:

git cherry-pick X Y # Replace with the appropriate commit IDs

Then push this branch to your fork, nuke the existing PR, and open a new one against upstream-with-commits. To get your fork's master back in order, do:

git checkout master
git push -f origin HEAD

git push -f will force a push, and overwrite any history in origin/master. Be warned that, if other people have cloned from your fork, it may cause problems for them.

Oh, and don't forget to delete master-preserve:

git branch -D master-preserve

Once you've cherry-picked from it, it's no longer necessary.