#!/usr/bin/env bash

# This essentially makes the current commit empty so you can see the full diff
# of the commit to be amended.
#
# This allows something similar to "Amend Last Commit" of git gui.

set -euo pipefail

old_commit=$(git rev-parse HEAD)

git-fmt() {
  git show -s --format="$1"
}

title=$(git-fmt %s)
message=$(git-fmt %B)

GIT_AUTHOR_NAME=$(git-fmt %an)
GIT_AUTHOR_EMAIL=$(git-fmt %ae)
GIT_AUTHOR_DATE=$(git-fmt %aD)
GIT_COMMITTER_NAME=$(git-fmt %cn)
GIT_COMMITTER_EMAIL=$(git-fmt %ce)
GIT_COMMITTER_DATE=$(git-fmt %cD)

export \
  GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE \
  GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL GIT_COMMITTER_DATE

git reset --soft HEAD~1
new_commit=$(git commit-tree -p HEAD 'HEAD^{tree}' -m "$message")

git update-ref -m "amend-last: $title" HEAD "$new_commit"

# If we're rebasing, git stores the current commit in rebase-merge/amend to
# know whether --continue should result in an amend. If we don't update this,
# --continue will complain that we have unstaged changes instead.
if git rev-parse -q --verify rebase-merge/amend; then
  git update-ref rebase-merge/amend "$new_commit" "$old_commit"
fi
