about summary refs log tree commit diff stats
path: root/pkgs/sources/scripts/source/apps/git-edit-index.sh
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/sources/scripts/source/apps/git-edit-index.sh')
-rwxr-xr-xpkgs/sources/scripts/source/apps/git-edit-index.sh98
1 files changed, 98 insertions, 0 deletions
diff --git a/pkgs/sources/scripts/source/apps/git-edit-index.sh b/pkgs/sources/scripts/source/apps/git-edit-index.sh
new file mode 100755
index 00000000..e73dc53c
--- /dev/null
+++ b/pkgs/sources/scripts/source/apps/git-edit-index.sh
@@ -0,0 +1,98 @@
+#!/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