This trick has saved me today and I’ve had to use it before… so I’m going to demonstrate how to do this here in my own words to save me Googling for every time!
So imagine the scenario. You’ve done a load of commits and you’re not ready to merge them back into master (or, even worse you’re in master) and you realise you made a massive mistake a few commits back and you need to just squash all the correction commits into it:
commit 6e0fa1b21e760aee2391f73c4905244a229abe8b
Author: Lee Packham <xxx>
Date: Sat Jul 2 12:47:31 2011 +0100
More tidy up (I'm a muppet)
commit abe08fd948f81f3366bc9a647e0d0c24ffe5fdc6
Author: Lee Packham <xxx>
Date: Sat Jul 2 12:46:14 2011 +0100
Tidy up
commit caefc1c0a8903009af2be8cd37df1ac40366fcce
Author: Lee Packham <xxx>
Date: Sun Jun 19 08:21:03 2011 -0700
Initial commit
Well that’s crap really isn’t it? So how do we go about sorting this? Well, we make a good use of rebase and tags to achieve this. There’s a nice answer to this on Stack Overflow – but I’ll replay it here. Props to Charles Bailey for this process.
So, here’s how we fix this:
# Checkout the top commit in a detached branch git checkout 6e0fa1b21e760aee2391f73c4905244a229abe8b # Now, do a soft reset back to the original commit git reset --soft caefc1c0a8903009af2be8cd37df1ac40366fcce # Now commit --amend it to squash it all git commit --amend # Then, tag this new detached commit git tag tmp # Now go back onto master git checkout master # Awesome now do a quick rebase and it'll replace the upstream with tmp git rebase --onto tmp 6e0fa1b21e760aee2391f73c4905244a229abe8b # No need for tmp now git tag -d tmp
Not overly simple – but brings, in this case, master to where I wanted it to be!
