Skip to content

Instantly share code, notes, and snippets.

@kirelagin
Last active April 20, 2020 19:30
Show Gist options
  • Save kirelagin/70abed1c291e42b198c9970bbe5368e5 to your computer and use it in GitHub Desktop.
Save kirelagin/70abed1c291e42b198c9970bbe5368e5 to your computer and use it in GitHub Desktop.
Quickly edit a file that was changed in the last git commit
#!/usr/bin/env bash
# SPDX-FileCopyrightText: 2020 Kirill Elagin <https://kir.elagin.me/>
# SPDX-License-Identifier: MPL-2.0
###
#
# Quickly edit a file that was changed in the last git commit.
#
# Sometimes you want to make a quick amendment to what you did in your last
# commit, but you already closed your editor. So you have to remember what
# file you edited, launch your editor, and type the file name again – it is
# somewhat cumbersome. Wouldn’t it be cool if you could just type:
#
# $ git fixup
#
# and have your editor launched with the file you edited in it? And if your
# last commit changed multiple files, you could choose which file to edit?
# This small script does exactly this.
#
# Use:
#
# * Download this script and put it somewhere on your $PATH.
# * $ git fixup
# * or $ git fixup <commit>
#
# Requirements:
#
# * git (obviously)
# * tput (probably comes with your distribution)
# * $EDITOR set to the editor you use
#
# https://gist.github.com/kirelagin/70abed1c291e42b198c9970bbe5368e5
###
changed=()
mode=''
while IFS= read -r -d '' line ; do
if [ -z "$mode" ]; then
mode="$line"
else
mode=''
changed+=( "$line" )
fi
done < <(git diff-tree --no-commit-id --name-status --diff-filter=AM -r -z "${@:-HEAD}")
chosen=''
if [ "${#changed[@]}" -lt 1 ]; then
printf 'No files to edit!\n'
exit 1
elif [ "${#changed[@]}" -eq 1 ]; then
chosen="${changed[0]}"
fi
if [ -z "$chosen" ]; then
i=1
for file in "${changed[@]}"; do
printf '[%d]\t%s\n' "$i" "$file"
i=$((i + 1))
done
printf '\n'
while [ -z "$chosen" ]; do
read -r -p 'Choose a file to edit: ' c || exit 1
if [ "$c" -ge 1 ] 2>/dev/null && [ "$c" -le "${#changed[@]}" ] 2>/dev/null; then
chosen="${changed[$((c - 1))]}"
else
tput cuu 1
printf 'Enter a number between %d and %d.\n' 1 "${#changed[@]}"
fi
done
fi
printf 'Editing `%s`\n' "$chosen"
# shellcheck disable=SC2086
exec $EDITOR "$chosen"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment