squash-last-commit.sh

By devin, 16 December, 2015

Sometimes you make a git commit, but there's a typo or syntax error in there by accident. I normally use git rebase -i HEAD~2 and then through the magic of vim I'm fairly productive at squashing the two commits together.

But wouldn't it be nice if there was a way to run one command to squash your most recent commit (which probably has a useless message like "typo" anyway) into the next most recent? Lucky for you, there is now!

#!/bin/bash
# /usr/local/bin/squash-last-commit.sh

export GIT_EDITOR='ed -s'

usage() {
  echo "Usage: $0 [-c] [-s]"
  exit 1
}

while [[ $# > 1 ]]; do
  case $1 in
    -c|--commit) SLC_COMMIT=true ;;
    -s|--squash) SLC_SQUASH=true ;;
    *) usage ;;
  esac
done

if [[ "$SLC_SQUASH" ]]; then
  git stash
fi

if [[ "$SLC_COMMIT" ]]; then
  git add -A .
  git commit -m "squashing"
fi

cat << EOF | git rebase -i HEAD~2
2s/^pick/fixup/
wq
EOF

if [[ "$SLC_SQUASH" ]]; then
  git stash pop
fi

Stick that file in /usr/local/bin/squash-last-commit.sh, then add a line to your ~/.bash_aliases saying alias slc=/usr/local/bin/squash-last-commit.sh.

Now you should be ready to use it:


slc -c # take any changes you haven't added yet and squash them into the most recent commit, retaining the same message

slc -s # git stash your current changes, squash the most recent two commits together, then git stash pop

I use slc -s if I want to add some, but not all, of my recent changes to a commit. I git add or git add -p, then I git commit with a name like 'squashme', and then I use slc -s to squash the changes I added into the last commit, leaving the rest of the changes intact.

 

Plain text

  • No HTML tags allowed.
  • Web page addresses and email addresses turn into links automatically.
  • Lines and paragraphs break automatically.