#!/usr/bin/env dash # shellcheck source=/dev/null SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH # needed for help() and version # shellcheck disable=2034 AUTHORS="Soispha" # shellcheck disable=2034 YEARS="2024" # shellcheck disable=2034 VERSION="1.0.0" # NAME is from the wrapper # shellcheck disable=SC2269 NAME="$NAME" help() { cat <<EOF Edit a file from the index. This script does not touch the unstaged variant of the file. USAGE: $NAME [OPTIONS] [--] FILES.. OPTIONS: -- Stop parsing options and interpret everything as an file. --help | -h Display this help and exit. --version | -v Display version and copyright information and exit. ARGUMENTS: FILES := [[ git diff --name-only --cached --diff-filter=AM ]] The files to edit. EOF } GIT_DIR="$(git rev-parse --show-toplevel)" materialize_file() { git diff --cached "$1" >"$GIT_DIR/.git/EDIT_INDEX_PATCH" git add "$1" git restore --staged "$1" cat "$1" >"$GIT_DIR/.git/EDIT_INDEX_FILE" git restore "$1" git apply "$GIT_DIR/.git/EDIT_INDEX_PATCH" "$EDITOR" "$1" git add "$1" mv "$GIT_DIR/.git/EDIT_INDEX_FILE" "$1" } edit() { files_to_add="$(mktmp)" realpath --relative-to=. "$@" >"$files_to_add" index_files="$(mktmp)" git diff --name-only --cached --diff-filter=AM >"$index_files" while read -r file; do if grep -q "$file" "$files_to_add"; then sed -i "s|$file||" "$files_to_add" materialize_file "$file" fi done <"$index_files" files_to_check="$(mktmp)" clean "$files_to_add" >"$files_to_check" if [ "$(wc -l <"$files_to_check")" -gt 0 ]; then warn "Could not edit every file:" cat "$files_to_add" fi } for arg in "$@"; do case "$arg" in "--help" | "-h") help exit 0 ;; "--version" | "-v") version exit 0 ;; "--") end_of_cli_options=true ;; esac [ "$end_of_cli_options" = "true" ] && break done edit "$@" # vim: ft=sh