wip
authorShane Jaroch <chown_tee@proton.me>
Sat, 17 Jan 2026 03:45:34 +0000 (22:45 -0500)
committerShane Jaroch <chown_tee@proton.me>
Sat, 17 Jan 2026 04:01:36 +0000 (23:01 -0500)
completions/gen_docs.sh
git-remote-gcrypt
tests/manual_test_clean_local.sh [new file with mode: 0755]

index 23277e8bcbc782dd2193f1606aaffb4f5b270f1c..93b2a921e01bbafc939a891d34db25c32fbb8824 100755 (executable)
@@ -86,13 +86,14 @@ SAFE_CMDS=$(echo "$COMMANDS_LIST" | sed 's/ / /g') # just space separated
 # We'll read the template line by line? No, sed is standard.
 # We use a temp file for the replacement string to avoid sed escaping hell for large blocks?
 # Or just keep it simple.
-sed "s/{commands}/$COMMANDS_LIST/" "$ZSH_TMPL" |
-       sed "s|{clean_flags_zsh}|$CLEAN_FLAGS_ZSH|" >"$ZSH_OUT"
+sed "s/{commands}/$COMMANDS_LIST/" "$ZSH_TMPL" \
+       sed "s|{clean_flags_zsh}|$CLEAN_FLAGS_ZSH|" >"$ZSH_OUT"
 
 # 6. Generate Fish
 echo "Generating Fish completions..."
 # Fish needs {not_sc_list} which matches {commands} (space separated)
-sed "s/{not_sc_list}/$COMMANDS_LIST/g" "$FISH_TMPL" |
+sed "s/{not_sc_list}/$COMMANDS_LIST/g" "$FISH_TMPL" \
+       |
        # Multi-line replacement in sed is hard. Use awk?
        # Or just injecting the string with escaped newlines.
        sed "s|{clean_flags_fish}|$CLEAN_FLAGS_FISH|" >"$FISH_OUT"
index 97bcc8bc4f69d6da327504795855b97aaa3765a1..74c2a584fd0aaf5ab9f5d434c03928ccd166e9d8 100755 (executable)
@@ -47,7 +47,7 @@ Options:
   check [URL]      Check if URL is a gcrypt repository
   clean [URL|REMOTE] Scan/Clean unencrypted files from remote
     clean --force        Actually delete files (default is scan only)
-    clean --init         Allow cleaning valid files (requires --force)
+    clean --init         Allow cleaning uninitialized repos (requires --force)
     clean --hard         Override safety checks (requires --force)
   stat [URL|REMOTE] Show diagnostics (file counts, tracked vs untracked)
 Git Protocol Commands (for debugging):
@@ -431,16 +431,17 @@ gitception_remove()
                else
                        if ! git rm --cached --ignore-unmatch -q "$2"; then
                                echo_info "Error: Failed to remove '$2' because it has local modifications."
-                               echo_info "Manual removal command: git rm --cached -f '$2'"
-                               
+
+                               # Hints for the user as requested
+                               echo_info "Hints:"
+                               echo_info "  1. To see all files with status differences:  git status"
+
                                suggest_args="--force --hard"
-                               # If we are in init mode (FORCE_INIT set), the user MUST pass --init again
                                if [ "${FORCE_INIT:-}" = "yes" ]; then
                                        suggest_args="--init $suggest_args"
                                fi
-                               
-                               echo_info "To force remove via tool, run:"
-                               echo_info "  git-remote-gcrypt clean $suggest_args $URL"
+                               echo_info "  2. To force clean the remote via tool:        git-remote-gcrypt clean $suggest_args $URL"
+
                                exit 1
                        fi
                fi
@@ -593,12 +594,16 @@ EOF
                        rm -f "$1"/"$fn_"
                done
        else
+               # gitception handling
                echo "$2" | while IFS= read -r fn_; do
                        gitception_remove "${1#gitception://}" "$fn_"
                done
        fi
 }
 
+REMOTE_REMOVE() { REMOVE "$@"; } # Alias if needed/used? No, just ensuring clean block.
+
+
 CLEAN_FINAL()
 {
        if isurl sftp "$1" || islocalrepo "$1" || isurl rsync "$1" || isurl rclone "$1"
@@ -1504,14 +1509,14 @@ cmd_clean()
        if [ "$Did_find_repo" != "yes" ]; then
                if [ "${FORCE_INIT:-}" = "yes" ]; then
                        echo_info "WARNING: No gcrypt manifest found, but --init specified."
-                       echo_info "WARNING: Proceeding to scan/clean potential unencrypted files."
+                       echo_info "WARNING: Proceeding to clean uninitialized repository."
                elif isnull "$FORCE_CLEAN"; then
                        echo_info "WARNING: No gcrypt manifest found."
                        echo_info "WARNING: Listing all files as potential garbage (dry-run)."
                else
                        echo_info "Error: No gcrypt manifest found on remote '$URL'."
                        echo_info "Aborting clean to prevent accidental data loss."
-                       echo_info "To force initiation of the repository as gcrypt (and delete all old objects):"
+                       echo_info "To force clean this uninitialized repository (e.g., to wipe before init):"
                        echo_info "  git-remote-gcrypt clean --init --force $URL"
                        exit 1
                fi
diff --git a/tests/manual_test_clean_local.sh b/tests/manual_test_clean_local.sh
new file mode 100755 (executable)
index 0000000..13100db
--- /dev/null
@@ -0,0 +1,113 @@
+#!/bin/sh
+set -e
+
+# Setup test environment
+echo "Setting up test environment..."
+PROJECT_ROOT="$(pwd)"
+mkdir -p .tmp
+TEST_DIR="$PROJECT_ROOT/.tmp/gcrypt_test"
+rm -rf "$TEST_DIR"
+mkdir -p "$TEST_DIR"
+
+REPO_DIR="$TEST_DIR/repo"
+REMOTE_DIR="$TEST_DIR/remote"
+
+mkdir -p "$REPO_DIR"
+mkdir -p "$REMOTE_DIR"
+
+# Initialize repo
+cd "$REPO_DIR"
+git init
+git config user.email "you@example.com"
+git config user.name "Your Name"
+
+# Create a few text files
+echo "content 1" >file1.txt
+echo "content 2" >file2.txt
+echo "content 3" >file3.txt
+git add file1.txt file2.txt file3.txt
+git commit -m "Initial commit with multiple files"
+
+# Setup gcrypt remote
+GCRYPT_BIN="$PROJECT_ROOT/git-remote-gcrypt"
+if [ ! -x "$GCRYPT_BIN" ]; then
+       echo "Error: git-remote-gcrypt binary not found at $GCRYPT_BIN"
+       exit 1
+fi
+
+# GPG Setup (embedded)
+export GNUPGHOME="$TEST_DIR/gpg"
+mkdir -p "$GNUPGHOME"
+chmod 700 "$GNUPGHOME"
+
+# Wrapper to suppress warnings, handle args, and FORCE GNUPGHOME
+cat <<EOF >"${GNUPGHOME}/gpg"
+#!/usr/bin/env bash
+export GNUPGHOME="$GNUPGHOME"
+set -efuC -o pipefail; shopt -s inherit_errexit
+args=( "\${@}" )
+for ((i = 0; i < \${#}; ++i)); do
+    if [[ \${args[\${i}]} = "--secret-keyring" ]]; then
+        unset "args[\${i}]" "args[\$(( i + 1 ))]"
+        break
+    fi
+done
+exec gpg "\${args[@]}"
+EOF
+chmod +x "${GNUPGHOME}/gpg"
+
+# Generate key
+echo "Generating GPG key..."
+gpg --batch --passphrase "" --quick-generate-key "Test <test@test.com>"
+
+# Initialize REMOTE_DIR as a bare git repo so gcrypt treats it as a git backend (gitception)
+# This is required to trigger gitception_remove
+git init --bare "$REMOTE_DIR"
+
+# Configure remote
+git remote add origin "gcrypt::$REMOTE_DIR"
+git config remote.origin.gcrypt-participants "test@test.com"
+git config remote.origin.gcrypt-signingkey "test@test.com"
+
+# Configure global git for test to avoid advice noise
+git config --global advice.defaultBranchName false
+
+export PATH="$PROJECT_ROOT:$PATH"
+
+echo "Pushing to remote..."
+# Explicitly use +master to ensure 'force' is detected by gcrypt to allow init
+git push origin +master
+
+# Create garbage on remote
+cd "$TEST_DIR"
+git clone "$REMOTE_DIR" raw_remote_clone
+cd raw_remote_clone
+git checkout master || git checkout -b master
+
+# Add multiple garbage files
+echo "garbage 1" >garbage1.txt
+echo "garbage 2" >garbage2.txt
+git add garbage1.txt garbage2.txt
+git commit -m "Add garbage files"
+git push origin master
+
+# Go back to local repo
+cd "$REPO_DIR"
+
+# Create conflicting local files (untracked but matching name, different content)
+# This simulates the "local modifications" error when `clean` tries to remove them.
+echo "local conflict 1" >garbage1.txt
+echo "local conflict 2" >garbage2.txt
+# Add them to local index so they are 'tracked' in the worktree, potentially confusing git rm against the temp index?
+# Or just ensure they exist. The user reported 'local modifications'.
+git add garbage1.txt garbage2.txt
+
+echo "Running clean --force (expecting failure and hints)..."
+echo "---------------------------------------------------"
+if ! git-remote-gcrypt clean --force origin; then
+       echo "---------------------------------------------------"
+       echo "Clean failed as expected."
+else
+       echo "Clean succeeded unexpectedly!"
+       exit 1
+fi