Search code examples
gitcommithistorygit-remote

Remove remote commits on the branch in GitHub


ALL,

I made a local branch in my fork a long time ago and pushed some changes to it. I then submitted a PR which was passed the CI build.

Now after some time I came back to the same machine I produced the PR but for some reason I didn't check which branch I was on and made couple of commits on the old branch and pushed them therefore screwing up the PR (it was not yet merged, due to the lack of the test code).

Now what I'd like to do is go to Github Web interface, remove those commits, but keep them locally, because I can just generate a patch on my local machine, remove those commits, switch to the new branch and apply the patch to it.

Or maybe even there is a better solution?

So how do I solve this mess?

Keep in mind - I intend to finish the PR with the test, but those are 2 completely unrelated things.

TIA!!

EDIT:

Everythig worked fine and my old branch on the original laptop is back to normal and the PR is now good.

However, in order to put the unit test I had to go to a different machine and do a git pull. For some unknown reason after that the git tree on that machine becomes clogged with everything including the bad commit.

I was able to revoke bad commits with git reset --hard N, but I fear that the same happen when I try to test my unit test on all platforms/different laptops which means my changes will be lost and I will need to redo them again for the UT on all different machines.

Can you help me here as well?

TIA!!


Solution

  • After some thought, my original answer is more complicated than strictly necessary, but I'll leave it below.

    The easiest way to get your original branch back to its old state and keep the new commits is to create a new branch then reset the old branch and force push. It looks like this:

    git checkout old-branch
    git branch new-branch
    git reset --hard <hash of commit you want to keep in old-branch>
    git push -f
    

    Alternatively you can use

    git reset --hard HEAD~n
    

    where n is the number of commits you want to remove from the old branch.

    Now you can do whatever you wish with the new branch, such as rebase it onto main. This might not be entirely necessary. If for example, your PR is merged, you will need to pull those changes into the new branch anyway before making the second PR. However, if you want to make a 2nd PR before the 1st is merged, then it is better to keep them separate until one of them is merged.

    TLDR

    The easiest way to fix a remote repository is to first make the changes locally and then push, possibly force push, to GitHub or other remote.

    Details

    You can do this all locally first, then push to GitHub to fix the PR. First, you should create a new branch and git cherry-pick the commits that you want to keep but remove from the other branch.

    Start by getting the hashes of the commits you want:

    git checkout old-branch
    git log --oneline --graph
    

    Copy the commit hashes for the commits you want to move. Then do

    git checkout -b new-branch main
    

    and for each of the hashes you copied:

    git cherry-pick <hash>
    

    Alternatively, you can do this more easily with git rebase. You only need the hash of the oldest commit you want to keep:

    git checkout -b new-branch old-branch
    git rebase --onto main <hash of oldest commit>~
    

    Now go back to your old branch and get rid of all the commits you no longer want:

    git checkout old-branch
    git reset --hard <hash of the first commit you want to keep on this branch>
    

    Finally force push:

    git push -f
    

    This will automatically update the PR back to its original state, if you used the correct hash for the git reset command.