about summary refs log tree commit diff stats
path: root/hm/soispha/pkgs/scripts/apps/git-edit-index.sh
diff options
context:
space:
mode:
Diffstat (limited to 'hm/soispha/pkgs/scripts/apps/git-edit-index.sh')
-rwxr-xr-xhm/soispha/pkgs/scripts/apps/git-edit-index.sh95
1 files changed, 95 insertions, 0 deletions
diff --git a/hm/soispha/pkgs/scripts/apps/git-edit-index.sh b/hm/soispha/pkgs/scripts/apps/git-edit-index.sh
new file mode 100755
index 00000000..368b99dc
--- /dev/null
+++ b/hm/soispha/pkgs/scripts/apps/git-edit-index.sh
@@ -0,0 +1,95 @@
+#!/usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.0.13" . %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:
+    --
+                            Ignore all flags after this point.
+
+    --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;
+            ;;
+        "--version" | "-v")
+            version;
+            ;;
+        "--")
+            break;
+        ;;
+    esac
+done
+
+edit "$@"
+
+# vim: ft=sh