Undo a merge by pull request?

If the pull was the last thing he did then

git reset --hard HEAD~1

There is a better answer to this problem, though I could just break this down step-by-step.

You will need to fetch and checkout the latest upstream changes like so, e.g.:

git fetch upstream
git checkout upstream/master -b revert/john/foo_and_bar

Taking a look at the commit log, you should find something similar to this:

commit b76a5f1f5d3b323679e466a1a1d5f93c8828b269
Merge: 9271e6e a507888
Author: Tim Tom <[email protected]>
Date:   Mon Apr 29 06:12:38 2013 -0700

    Merge pull request #123 from john/foo_and_bar

    Add foo and bar

commit a507888e9fcc9e08b658c0b25414d1aeb1eef45e
Author: John Doe <[email protected]>
Date:   Mon Apr 29 12:13:29 2013 +0000

    Add bar

commit 470ee0f407198057d5cb1d6427bb8371eab6157e
Author: John Doe <[email protected]>
Date:   Mon Apr 29 10:29:10 2013 +0000

    Add foo

Now you want to revert the entire pull request with the ability to unrevert later. To do so, you will need to take the ID of the merge commit.

In the above example the merge commit is the top one where it says "Merged pull request #123...".

Do this to revert the both changes ("Add bar" and "Add foo") and you will end up with in one commit reverting the entire pull request which you can unrevert later on and keep the history of changes clean:

git revert -m 1 b76a5f1f5d3b323679e466a1a1d5f93c8828b269

Look at your commit graph (with gitk or a similar program). You will see commits from the pull request, and you will see your own commits, and a merge commit (if it was not a fast-forward merge). You just have to find the last of your own commits before the merge, and reset the branch to this commit.

(If you have the branch's reflog, it should be even easier to find the commit before the merge.)


(Edit after more information in comments:)

Okay, lets look at the graph:

screenshot 1

I assume the last (rightmost) commit was your wrong merge by pull request, which merged the blue line seen here. Your last good commit would be the one before on the black line, here marked in red:

enter image description here

Reset to this commit, and you should be fine.

This means, in your local working copy do this (after making sure you have no more uncommitted stuff, for example by git stash):

git checkout master
git reset --hard 7a62674ba3df0853c63539175197a16122a739ef
gitk 

Now confirm that you are really on the commit I marked there, and you will see none of the pulled stuff in its ancestry.

git push -f origin master

(if your github remote is named origin - else change the name).

Now everything should look right on github, too. The commits will still be in your repository, but not reachable by any branch, thus should not do any harm there. (And they will be still on RogerPaladin's repository, of course.)

(There might be a Github specific web-only way of doing the same thing, but I'm not too familiar with Github and its pull request managing system.)

Note that if anyone else already might have pulled your master with the wrong commit, they then have the same problem as you currently have, and can't really contribute back. before resetting to your new master version.

If it is likely that this happened, or you simply want to avoid any problems, use the git revert command instead of git reset, to revert the changes with a new commit, instead of setting back to an older one. (Some people think you should never do reset with published branches.) See other answers to this question on how to do this.

For the future:

If you want only some of the commits of RogerPaladin's branch, consider using cherry-pick instead of merge. Or communicate to RogerPaladin to move them to a separate branch and send a new pull request.