Convenient squashing from the command line
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



When I first wrote this I was unaware of git commit --squash. This feature provides similiar functionality to that provided by the scripts in this repository.

git-squash is useful when you want to squash an already existing commit into another commit. git-squash-files has no analogue in the current git distribution.

git squash - Squash commits faster

When iterating a patch-set, I often find myself squashing with git-rebase -i. For instance, say you have a repository that looks like this,

A <-- B <-- C

You find a silly mistake in B, which you correct in a new commit D yielding,

A <-- B <-- C <-- D

To produce a clean revision history (or to hide your silly mistake), you'd want to absorb D into B to produce,

A <-- B+D <-- C

To do this with git rebase, you'd need to run git rebase -i A, look through a list of commits, find D, move it after B, changes its flag to squash, save, and exit. This kills time.

Enter git squash,

$ git squash D --into B

Squashing multiple commits is trivial,

$ git squash F Z D --into B

git-squash will automatically put F, Z, and D into topological order before squashing to minimize the chance for conflicts.

git squash-files - Squash even faster

Say you are working on you pet project one afternoon and add a lovely new feature to turtle-feeder.c. Confident in your work, you move on to add more lovely features elsewhere in the repository without testing (since bugs never happen, right?).

Several hours of hacking and numerous finished features later, you go to test your day's work. It doesn't take long to realize that you introduced a trivial bug into turtle-feeder.c, which you handily fix and commit. Being a strong believer in clean revision history, you want to absorb this fix into your original commit.

Previously this would have involved using git rebase -i and squashing the fix into the original commit. git-squash described above makes this process slightly easier,

$ git squash FIX --into=ORIGINAL

But this of course assumes that you know the commit id of ORIGINAL. This seems silly; in all likelihood ORIGINAL is one of the last commits to touch turtle-feeder.c. Why can't git just do what you want?

git-squash-files does just that,

$ git squash-files HEAD^..HEAD
Choose a commit to squash
  d210978 silly turtle-feeder fix
  1. 7797f05 turtle-feeder: introduce new feature
  2. 2c6ba60 turtle-feeder: don't feed twice on saturday
  3. a849213 Various fixes
  4. 4ff91b1 turtle-feeder: initial commmit
  0. Skip this commit

[1]? <Enter>

Squashed d210978d7c077cb99954898c8890958a7bdfba15 into 7797f05af13897a9a588cc076dc2b163ff7d94d7

In particular, git-squash-files iterates through each of the commits in the given range and for each one,

  1. Ensures that the commit touches only one file
  2. Finds the recent commits which touch this file
  3. Prompts the user to select one of these to squash into
  4. Uses git squash to squash the commit


To install, just use the included makefile,

$ sudo make install

Optionally, define the DESTDIR variable to specify a different installation root (default is /usr/local).