Lee Packham

Software Engineer, UX Designer, Opinionated

Git: Squashing Commits Without Merging a Thing

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 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!