Fixing a “git mess” with cherry pick (from the command line)

Yesterday we were remotely pair programming (by me sharing my screen and my colleague Alex looking at it), and at some point I had to send a PR with a test change to validate the process would trigger the automation he had set up… but turns out he had changed something on the repo after I had forked and cloned it, and so I had a conflict!

I somehow resolved it (note to self: talking while resolving conflicts is not a good idea) but when I then pushed my branch to GitHub and created the pull request, it would not run automation because of that conflict (even if I had ‘resolved’ it).

I did not want to clone again and apply the changes… and neither wanted Alex! He said that everything is fixable with Git, so he showed me how to get myself out of this situation.

First we add the upstream remote to our repository, so we can check it out:

git remote add upstream https://github.com/user/repo.git

We fetch the data from the upstream repo:

git fetch upstream

Run a git log to find the hash of the commit we do want to keep (the Good Commit):

git log

Say it produces something like this:

commit 0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD
Author: sole
Date:   Thu Mar 2 16:02:03 2017 +0000

    AAAAARGHHHH

commit 1337133713371337133713371337133713371337
Author: sole
Date:   Thu Mar 2 15:55:26 2017 +0000

    testing at the request of @ochameau

commit 0b225a66cf3ad67b3c67360d0e7c1e329ca3ce34
Author: Alexandre Poirot
Date:   Tue Feb 28 11:57:23 2017 +0100

    Upload screenshot and status

We don’t want the last commit (0BAD0BAD), we want the previous one (13371337). So make a note of that hash somewhere.

Now we check out their master branch (which we want to use as the base for our modification):

git checkout upstream/master

And we tell git to apply our changes from The Good Commit, using the hash we found before:

git cherry-pick 1337133713371337133713371337133713371337

Since I didn’t even change the same file he changed in his other commit, this applied neatly. No conflicts!

The problem is that my local repository is now different from the GitHub copy, because I had pushed a version which had an additional commit to resolve ‘the conflict’ (I tell you, this was quite messy!)

The solution is to force push to my GitHub repository (gasp!):

git push origin HEAD:master -f

And you don’t need to update the PR that had “conflicts”–GitHub already picks that you updated the repository, and since there are no conflicts anymore, the integration stuff works 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *