Git: Automatically Squashing at the Prompt

I do a huge amount of squashing, every day of the week. Ever the kind of engineer who wishes to optimize every single redundant operation, I wrote a simple script and then aliased it in my shell. When I do a commit that I know I will be squashing into the previous commit, I simply do a “git commit -m SQUASH -a” and then run “SQUASH_LAST” (my alias, which is autocompleted) to run the squash. The script verifies that the last commit message starts with “SQUASH” (for verification/sanity), executes the squash, and then prints the current commit, previous commit, and final commit revisions.

It is extremely convenient and saves a ton of time and annoyingly-repetitive steps.

The script (which I put in my home):

#!/bin/bash -e

HEAD_COMMIT_MESSAGE=$(git log --format=%B -1 HEAD)

# For safety. Our use-case is usually to always just squash into a commit
# that's associated with an active change. We really don't want lose our head
# and accidentally squash something that wasn't intended to be squashed.
if [[ "${HEAD_COMMIT_MESSAGE}" != SQUASH* ]]; then
    echo "SQUASH: Commit to be squashed should have 'SQUASH' as its commit-message."
    exit 1
fi

_FILEPATH=$(mktemp)
git log --format=%B -1 HEAD~1 >"${_FILEPATH}"

echo "Initial head: $(git rev-parse HEAD)"

git reset --soft HEAD~2 >/dev/null

echo "Head after reset: $(git rev-parse HEAD)"

git commit -F $_FILEPATH >/dev/null
rm $_FILEPATH

echo "Head after commit: $(git rev-parse HEAD)"

echo

The alias (for completeness):

alias SQUASH_LAST='<filepath>'

It really is about the little things.

I have also put the script into a gist.

Advertisements