Git/GitHub: Squashing all commits before sending a pull request
My colleague Michael has been doing some work to make it easier for people to import data into neo4j and his latest attempt is neo4j-shell-tools which adds some additional commands to the neo4j-shell.
I’ve spent a bit of time refactoring the readme which I’d done on a branch of my fork of the repository and consisted of 46 commits, most changing 2 or 3 lines.
I wanted to send Michael a pull request on Github but first I needed to squash all my commits down into a single one.
I initially thought there might be a way that I could do that via Github but I couldn’t see how to do that and eventually came across a post on Steve Klabnik’s blog which explained what I needed to do.
This is what my .git/config looked like initially:
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = git@github.com:mneedham/neo4j-shell-tools.git
[branch "master"]
remote = origin
merge = refs/heads/master
[remote "base"]
url = git@github.com:jexp/neo4j-shell-tools.git
fetch = +refs/heads/*:refs/remotes/base/*
[branch "readme"]
remote = origin
merge = refs/heads/readme
I had all my commits on the 'readme' branch but the easiest approach seemed to be to create another branch on which I could squash all my commit - I called that branch 'readme-pull':
$ git branch readme-pull
$ git checkout readme-pull
Switched to branch 'readme-pull'
I then synced myself with Michael’s repository:
$ git fetch base
remote: Counting objects: 77, done.
remote: Compressing objects: 100% (18/18), done.
remote: Total 43 (delta 15), reused 40 (delta 12)
Unpacking objects: 100% (43/43), done.
From github.com:jexp/neo4j-shell-tools
e81c431..c4e94f6 master -> base/master
$ git rebase base/master
First, rewinding head to replay your work on top of it...
I then had to handle any conflicts when applying my changes on top of Michael’s master repository and then I was in a position to squash all my commits!
We can use rebase in interactive mode to do this and I’ve always done so by counting back how many commits I want to squash, so in this case it was 35: ~bash $ git rebase -i HEAD~35 pick 141d0ae updating readme with link pick 94f8f93 more updating pick 03de50b readme updates pick 4e60332 more updates pick 3447d50 simplifying pick d577520 tweaks pick 2d993d4 more pick f948582 list of commands pick 713aae8 updating ~
I later realised that I could have just passed in the last commit hash from the master to the rebase command i.e. ~bash commit c4e94f668223d53f6c7364d19aa965d09ea7eb00 Author: Michael Hunger <github@jexp.de> Date: Fri Jul 12 10:33:55 2013 +0200 fixed test ~ ~bash $ git rebase -i c4e94f668223d53f6c7364d19aa965d09ea7eb00 ~
I then set all but the first commit to 'squash' and pushed to my repository: ~bash $ git push -u origin readme-pull:readme-pull ~
Finally I issued my pull request and Michael merged it in!
About the author
I'm currently working on short form content at ClickHouse. I publish short 5 minute videos showing how to solve data problems on YouTube @LearnDataWithMark. I previously worked on graph analytics at Neo4j, where I also co-authored the O'Reilly Graph Algorithms Book with Amy Hodler.