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 = firstname.lastname@example.org:mneedham/neo4j-shell-tools.git [branch "master"] remote = origin merge = refs/heads/master [remote "base"] url = email@example.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.
commit c4e94f668223d53f6c7364d19aa965d09ea7eb00 Author: Michael Hunger <firstname.lastname@example.org> Date: Fri Jul 12 10:33:55 2013 +0200 fixed test
$ git rebase -i c4e94f668223d53f6c7364d19aa965d09ea7eb00
I then set all but the first commit to 'squash' and pushed to my repository:
$ git push -u origin readme-pull:readme-pull
Finally I issued my pull request and Michael merged it in!