Thursday, June 23, 2016

Squash several commits in git into one

I had several commits on my branch, all related to the same change. Instead of merging all the commits into master, I wanted to squash all of them into one, and merge the single commit.  Less junk on the master branch that way.

This https://gist.github.com/nicholashagen/2855167 has a shows a very nice way to merge and squash together. But since I use bitbucket(aka stash) and pull requests, the git merge --squash command doesn't work.

I had been looking for a slick way of squashing commits before generating a pull request, and recently found it.

I had 4 commits I wanted to squash (all the ones with the comment "Add sonar jobs for all apps") on the branch feature/add-sonar:

git log shows me the commit IDs


/git/docker-jenkins-master  on  feature/add-sonar * $ git log
commit 02041bddd50de5d5bd40bd3146ae44323fabb6a7
Author: Somaiah Kumbera <somaiah.kumbera@somewhere.com>
Date:   Thu Jun 23 08:50:42 2016 +0200

    Add sonar jobs for all apps

commit 17f11e416982bf486da2db732b3e1de580c59877
Author: Somaiah Kumbera <somaiah.kumbera@somewhere.com>
Date:   Wed Jun 22 14:15:35 2016 +0200

    Add sonar jobs for all apps

commit cc396d605bfe0db279d2beb11833880b3365edc7
Author: Somaiah Kumbera <somaiah.kumbera@somewhere.com>
Date:   Wed Jun 22 13:07:43 2016 +0200

    Add sonar jobs for all apps

commit affcae8432efef916d353dc4f204d4507422eebd
Author: Somaiah Kumbera <somaiah.kumbera@somewhere.com>
Date:   Wed Jun 22 13:04:52 2016 +0200

    Add sonar jobs for all apps

commit 29fa6593a0bc619d269c4b84b8f857b2dbe466e8
Merge: 78f0f8a 9751714
Author: Someone Else <someone.else@somewhere.com>
Date:   Wed Jun 1 10:29:49 2016 +0200

   Something unrelated


git rebase -i allows me to squash the ones from the current point (HEAD) back to the last n commits (in my case n = 4)



/git/docker-jenkins-master  on  feature/add-sonar * $ git rebase -i HEAD~4


At this point I got an editor open up with the list of the last 4 commits, so I could do something with them:



pick affcae8 Add sonar jobs for all apps
pick cc396d6 Add sonar jobs for all apps
pick 17f11e4 Add sonar jobs for all apps
pick 02041bd Add sonar jobs for all apps



Notice that the commits are in reverse chronological order - so the oldest one shows up first. I wanted to pick the oldest one, and squash the others. So I changed the text to look like this:



pick affcae8 Add sonar jobs for all apps
f cc396d6 Add sonar jobs for all apps
f 17f11e4 Add sonar jobs for all apps
f 02041bd Add sonar jobs for all apps


Ctrl-X (to save)
y (to confirm)

The rebase is successful:



[detached HEAD 4d51329] Add sonar jobs for all apps
 2 files changed, 89 insertions(+), 1 deletion(-)
 create mode 100644 path/dir/filename.xml
Successfully rebased and updated refs/heads/feature/add-sonar.



Now all you have to do is push. But you need to force push.



/git/docker-jenkins-master  on  feature/add-sonar * $ git push --force


Now git log shows only 1 commit:



/git/docker-jenkins-master  on  feature/add-sonar  $ git log
commit 4d513295b564ad253c6d738496163c7d392af3d6
Author: Somaiah Kumbera <somaiah.kumbera@somewhere.com>
Date:   Wed Jun 22 13:04:52 2016 +0200

    Add sonar jobs for all apps

commit 29fa6593a0bc619d269c4b84b8f857b2dbe466e8
Merge: 78f0f8a 9751714
Author: Someone Else <someone.else@somewhere.com>
Date:   Wed Jun 1 10:29:49 2016 +0200

   Something unrelated


Now you can merge that single commit in any way you choose :)

No comments:

Post a Comment