]> Nutra Git (v1) - gamesguru/git-remote-gcrypt.git/commitdiff
wip
authorShane Jaroch <chown_tee@proton.me>
Fri, 9 Jan 2026 16:12:56 +0000 (11:12 -0500)
committerShane Jaroch <chown_tee@proton.me>
Fri, 9 Jan 2026 16:12:56 +0000 (11:12 -0500)
git-remote-gcrypt
tests/test-clean-command.sh

index 4e29096865f18b1e7da6bde60868aa4bf00c9cb0..011fddd2fb5865aa5a5ab39ed5a014d6b38f1ba2 100755 (executable)
@@ -760,7 +760,7 @@ ensure_connected()
                                                echo_info "ERROR: Remote repository contains unencrypted or unknown files!"
                                                echo_info "To protect your privacy, git-remote-gcrypt will NOT push to this remote."
                                                echo_info "Found unexpected files: $(echo "$early_bad_files" | head -n 3 | tr '\n' ' ')"
-                                               echo_info "To see full list of unexpected files, use: git-remote-gcrypt clean --force $URL"
+                                               echo_info "To see unencrypted files, use: git-remote-gcrypt clean $URL"
                                                echo_info "To fix and remove these files, use: git-remote-gcrypt clean --force $URL"
                                                exit 1
                                        fi
@@ -1356,6 +1356,11 @@ elif [ "$NAME" = "gcrypt-clean" ]; then
                echo_die "Could not connect to $URL."
        fi
 
+       if [ "$Did_find_repo" != "yes" ]; then
+               echo_die "Error: No gcrypt manifest found on remote '$URL'." \
+                       "Aborting clean to prevent accidental data loss."
+       fi
+
        # Get all files in the remote
        # For rsync backends, list files directly via rsync --list-only (awk extracts filename).
        # For rclone backends, list files via rclone lsf.
index f39d51187040475f5d56697ea343b9ca10be29a8..a2f3e878a0ed09640bf97561945fe46f8eba14bd 100755 (executable)
@@ -19,8 +19,13 @@ print_err() { echo -e "${RED}✗ $*${NC}"; }
 SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
 export PATH="$SCRIPT_DIR:$PATH"
 
+# Isolate git config from user environment
+export GIT_CONFIG_SYSTEM=/dev/null
+export GIT_CONFIG_GLOBAL=/dev/null
+
 # Suppress git advice messages
-GIT="git -c advice.defaultBranchName=false"
+# Note: git-remote-gcrypt reads actual config files, not just CLI -c options
+GIT="git -c advice.defaultBranchName=false -c commit.gpgSign=false"
 
 # --------------------------------------------------
 # Set up test environment
@@ -31,11 +36,44 @@ trap 'rm -rf "$tempdir"' EXIT
 
 print_info "Setting up test environment..."
 
+# --------------------------------------------------
+# GPG Setup (Derived from system-test.sh)
+# --------------------------------------------------
+export GNUPGHOME="${tempdir}/gpg"
+mkdir "${GNUPGHOME}"
+
+# Wrapper to suppress obsolete warnings
+cat <<'EOF' >"${GNUPGHOME}/gpg"
+#!/usr/bin/env bash
+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
+(
+       gpg --batch --passphrase "" --quick-generate-key "Test <test@test.com>"
+)
+
+# --------------------------------------------------
+# Git Setup
+# --------------------------------------------------
+
 # Create a bare repo with dirty files
 $GIT init --bare "$tempdir/remote.git" >/dev/null
 cd "$tempdir/remote.git"
 $GIT config user.email "test@test.com"
 $GIT config user.name "Test"
+$GIT config gpg.program "${GNUPGHOME}/gpg"
+# Needed for encryption to work during setup
+$GIT config gcrypt.participants "test@test.com"
 
 # Add multiple unencrypted files
 echo "SECRET=abc" >"$tempdir/secret1.txt"
@@ -71,29 +109,29 @@ output=$("$SCRIPT_DIR/git-remote-gcrypt" clean 2>&1 || :)
 assert_grep "Usage: git-remote-gcrypt clean" "$output" "clean shows usage when no URL/remote found"
 
 # --------------------------------------------------
-# Test 2: Default scan-only mode
+# Test 2: Safety Check (Abort on non-gcrypt)
 # --------------------------------------------------
-print_info "Test 2: Default scan-only mode..."
+print_info "Test 2: Safety Check (Abort on non-gcrypt)..."
 cd "$tempdir/remote.git"
-output=$("$SCRIPT_DIR/git-remote-gcrypt" clean "$tempdir/remote.git" 2>&1)
-assert_grep "secret1.txt" "$output" "clean identifies unencrypted files"
-assert_grep "NOTE: This is a scan" "$output" "clean defaults to scan-only mode"
+output=$("$SCRIPT_DIR/git-remote-gcrypt" clean "$tempdir/remote.git" 2>&1 || :)
+assert_grep "Error: No gcrypt manifest found" "$output" "clean aborts on non-gcrypt repo"
 
 if $GIT ls-tree HEAD | grep -q "secret1.txt"; then
-       print_success "Files still exist after default scan"
+       print_success "Files preserved (Safety check passed)"
 else
-       print_err "Default scan incorrectly deleted files!"
+       print_err "Files deleted despite safety check!"
        exit 1
 fi
 
 # --------------------------------------------------
-# Test 3: Remote resolution
+# Test 3: Remote resolution (Abort on non-gcrypt)
 # --------------------------------------------------
 print_info "Test 3: Remote resolution..."
 mkdir -p "$tempdir/client" && cd "$tempdir/client" && $GIT init >/dev/null
+$GIT config gpg.program "${GNUPGHOME}/gpg"
 $GIT remote add origin "$tempdir/remote.git"
-output=$("$SCRIPT_DIR/git-remote-gcrypt" clean origin 2>&1)
-assert_grep "Checking remote: $tempdir/remote.git" "$output" "clean resolved 'origin' to URL"
+output=$("$SCRIPT_DIR/git-remote-gcrypt" clean origin 2>&1 || :)
+assert_grep "Error: Remote 'origin' is not a gcrypt:: remote" "$output" "clean aborts on resolved non-gcrypt remote"
 
 # --------------------------------------------------
 # Test 4: Remote listing
@@ -101,19 +139,78 @@ assert_grep "Checking remote: $tempdir/remote.git" "$output" "clean resolved 'or
 print_info "Test 4: Remote listing..."
 $GIT remote add gcrypt-origin "gcrypt::$tempdir/remote.git"
 output=$("$SCRIPT_DIR/git-remote-gcrypt" clean 2>&1 || :)
-assert_grep "Available gcrypt remotes:" "$output" "clean lists remotes"
+assert_grep "Available remotes:" "$output" "clean lists remotes"
 assert_grep "gcrypt-origin" "$output" "clean listed 'gcrypt-origin'"
 
 # --------------------------------------------------
-# Test 5: Force cleanup
+# Test 5: Clean Valid Gcrypt Repo
 # --------------------------------------------------
-print_info "Test 5: Force cleanup..."
-"$SCRIPT_DIR/git-remote-gcrypt" clean "$tempdir/remote.git" --force >/dev/null 2>&1
-if $GIT -C "$tempdir/remote.git" ls-tree HEAD 2>/dev/null | grep -q "secret"; then
-       print_err "Files still exist after force cleanup!"
+print_info "Test 5: Clean Valid Gcrypt Repo..."
+
+# 1. Initialize a valid gcrypt repo
+mkdir "$tempdir/valid.git" && cd "$tempdir/valid.git" && $GIT init --bare >/dev/null
+cd "$tempdir/client"
+$GIT config user.name "Test"
+$GIT config user.email "test@test.com"
+$GIT config user.signingkey "test@test.com"
+# Create content to push
+echo "valid content" >content.txt
+$GIT add content.txt
+$GIT commit -m "init valid"
+# Push to intialize
+set -x
+$GIT push -f "gcrypt::$tempdir/valid.git" master:master || {
+       set +x
+       print_err "Git push failed"
+       exit 1
+}
+set +x
+
+print_info "Initialized valid gcrypt repo"
+
+# 2. Inject garbage file into the remote git index/tree
+cd "$tempdir/valid.git"
+GREF="refs/gcrypt/gitception"
+if ! $GIT rev-parse --verify "$GREF" >/dev/null 2>&1; then
+       print_err "Gref $GREF not found in remote!"
+       exit 1
+fi
+
+GARBAGE_BLOB=$(echo "GARBAGE DATA" | $GIT hash-object -w --stdin)
+CURRENT_TREE=$($GIT rev-parse "$GREF^{tree}")
+export GIT_INDEX_FILE=index.garbage
+$GIT read-tree "$CURRENT_TREE"
+$GIT update-index --add --cacheinfo 100644 "$GARBAGE_BLOB" "garbage_file"
+NEW_TREE=$($GIT write-tree)
+rm index.garbage
+PARENT=$($GIT rev-parse "$GREF")
+NEW_COMMIT=$(echo "Inject garbage" | $GIT commit-tree "$NEW_TREE" -p "$PARENT")
+$GIT update-ref "$GREF" "$NEW_COMMIT"
+
+# Verify injection
+if ! $GIT ls-tree -r "$GREF" | grep -q "garbage_file"; then
+       print_err "Failed to inject garbage_file into $GREF"
+       exit 1
+fi
+print_info "Injected garbage_file into remote $GREF"
+
+# 3. Scan (expect to find garbage_file)
+set -x
+output=$("$SCRIPT_DIR/git-remote-gcrypt" clean "gcrypt::$tempdir/valid.git" 2>&1)
+set +x
+assert_grep "garbage_file" "$output" "clean identified unencrypted file in valid repo"
+assert_grep "NOTE: This is a scan" "$output" "clean scan-only mode confirmed"
+
+# 4. Clean Force
+"$SCRIPT_DIR/git-remote-gcrypt" clean "gcrypt::$tempdir/valid.git" --force >/dev/null 2>&1
+
+# Verify garbage_file is GONE from the GREF tree
+UPDATED_TREE=$($GIT rev-parse "$GREF^{tree}")
+if $GIT ls-tree -r "$UPDATED_TREE" | grep -q "garbage_file"; then
+       print_err "Garbage file still exists in remote git tree after CLEAN FORCE!"
        exit 1
 else
-       print_success "Files removed after clean --force"
+       print_success "Garbage file removed successfully."
 fi
 
 # --------------------------------------------------