#!/usr/bin/env bash set -o errexit -o nounset -o pipefail if ! git rev-parse --is-inside-work-tree > /dev/null 2>&1 ; then echo 'Not inside a Git repository.' >&2 exit 1 fi if ! git rev-parse HEAD > /dev/null 2>&1 ; then echo "Where's your HEAD?" >&2 exit 1 fi has_staged_changes= git diff --cached --ignore-submodules --quiet || has_staged_changes=1 has_unstaged_changes= git diff --ignore-submodules --quiet || has_unstaged_changes=1 if [ -z "$has_staged_changes" ] && [ -z "$has_unstaged_changes" ]; then echo 'No staged or unstaged changes, seemingly?' >&2 exit 1 fi add=-a [ -n "$has_staged_changes" ] && add= numof_parents="$( git rev-list --parents -n 1 HEAD | wc --words )" if [ "$numof_parents" -eq 1 ]; then dest_ref=--root elif [ "$numof_parents" -eq 2 ]; then dest_ref='HEAD^^' else echo 'Sure you want to fixup a merge commit?' >&2 exit 1 fi git commit $add --fixup=HEAD stash= [ -n "$has_staged_changes" ] && [ -n "$has_unstaged_changes" ] && stash=1 unstash() { git stash pop --quiet } if [ -n "$stash" ]; then git stash push --quiet trap unstash EXIT fi GIT_EDITOR=true git rebase -i --autosquash "$dest_ref"