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
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"
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
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
# --------------------------------------------------