O'Reilly

Squash Commits with Git

By on  

I'm not a git expert but I know enough git to get by, and surely know enough git to appreciate its ease of use over svn. A while ago I published some basic git commands to that go slightly beyond basic cloning and commits, and should handle most git interactions. Today's mini git lesson involves squashing multiple commits into one, allowing for easier pull request review and merge management.

Start by making changes to the feature branch you're doing work on. Let's assume that these changes span a few commits and I want to consolidate them into one commit. The first step involves making sure the master branch is up to date with the destination repo's master branch:

# switch to master branch
git checkout master

# ensure our master is up to date
git pull remoteRepoName master

With the master branch up to date, we'll use git rebase to consolidate:

git rebase -i master

That command will show a list of each commit, as such:

pick fb554f5 This is commit 1
pick 2bd1903 This is commit 2
pick d987ebf This is commit 3

# Rebase 9cbc329..d987ebf onto 9cbc329
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

Edit the summary shown to you by the rebase command, leaving the commit you want to be the main commit as "pick" and changing all subsequent "pick" commands as "squash":

pick fb554f5 This is commit 1
squash 2bd1903 This is commit 2
squash d987ebf This is commit 3

# Rebase 9cbc329..d987ebf onto 9cbc329
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

Write/quit past the editor twice (the second screen would allow you to change the commit message, though I like to keep it the same). At this point, your commits are squashed into one. Run the following command to force a push of the new, consolidated commit:

git push -f

This forced push updates the source repository and our commits have become one. If you had already submitted a pull request at GitHub, the pull request would now show only one commit! With one consolidated commit, code review becomes much, much easier!

Track.js Error Reporting

Recent Features

  • 9 Mind-Blowing Canvas Demos

    The <canvas> element has been a revelation for the visual experts among our ranks.  Canvas provides the means for incredible and efficient animations with the added bonus of no Flash; these developers can flash their awesome JavaScript skills instead.  Here are nine unbelievable canvas demos that...

  • CSS Filters

    CSS filter support recently landed within WebKit nightlies. CSS filters provide a method for modifying the rendering of a basic DOM element, image, or video. CSS filters allow for blurring, warping, and modifying the color intensity of elements. Let's have...

Incredible Demos

  • Chris Coyier&#8217;s Favorite CodePen Demos

    David asked me if I'd be up for a guest post picking out some of my favorite Pens from CodePen. A daunting task! There are so many! I managed to pick a few though that have blown me away over the past few months. If you...

  • Create a Context Menu with Dojo and Dijit

    Context menus, used in the right type of web application, can be invaluable.  They provide shortcut methods to different functionality within the application and, with just a right click, they are readily available.  Dojo's Dijit frameworks provides an easy way to create stylish, flexible context...

Discussion

  1. bartaz

    Please note that it’s not a very good practice to squash commits that have already been pushed to public repository (like github) – if anyone had already forked or cloned the repo before they were squashed they may end up with broken commit tree, unable to merge any new changed (without some more tricky cleaning commands)

    So it’s much better to remember to squash commits before they are pushed anywhere.

    • Is it even possible to squash after a push? I just pushed a couple of commits and thought I would play with squashing and it wouldn’t show me those commits as something I could squash.

    • It should be possible, yes. I’ve done it many times.

  2. Ashley Camba

    small note: afaik, push -f is a bad idea: http://www.randyfay.com/node/89

    unless you really know what you are doing, stay away from push force.

  3. Why all the complication? Why not just:

    git merge –squash branch-name

  4. Amit

    I think this is the most straight forward and user friendly answer. I especially like the part where you mentioned that a new screen will open and it will allow you to change your commit message. This is helpful for a user like me who isn’t familiar with git.
    Thanks for helping.

  5. Petar

    I was looking for that git push -f
    There is a tone of tuts about squashing but they are all missing that part. Thank you

  6. Ross

    Why am I always 3 years behind your posts? Haha, thanks for all the consistently great info over the years (first found your blog in 2009, I think)

  7. Helpful post, thanks.

  8. Thanks – can always rely on you to give a clear explanation.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Recently on David Walsh Blog

  • OSCON Portland:  Conference  Discount!

    O'Reilly puts on the best web industry conferences in the world.  These conferences include Fluent Conference, Velocity Conference, and the upcoming OSCON in Portland, Oregon from July 20-24.  Open Source Convention (OSCON) is a conference that focuses specifically on open source developers and the tools and possibilities...

  • Follow Redirects with cURL

    I love playing around with cURL. There's something about loading websites via command line that makes me feel like some type of smug hacker, just like tweeting from command line does. I recently cURL'd the Google homepage and saw the following: I found it weird that Google...

  • Developers Have WordPress, Amateurs Have Squarespace, Professional Designers Have the NEW Webydo!

    Web design platforms have traditionally come in one of two varieties. There are the solutions like WordPress and Drupal that are incredibly powerful, but an understanding of web development and coding is required to be able to use those platforms effectively. On the other side of the...

  • Chris Coyierâs Favorite CodePen Demos II

    Hey everyone! Before we get started, I just want to say it’s damn hard to pick this few favorites on CodePen. Not because, as a co-founder of CodePen, I feel like a dad picking which kid he likes best (RUDE). But because there is just so...

  • GSAP + SVG For Power Users: Motion Along A Path

    Now that the GreenSock API is picking up steam, there are many tutorials and Getting Started guides out there to provide good introductions to the library, not to mention GreenSock’s own Forum and Documentation. This article isn’t intended for beginners, but rather a...