# 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"
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):
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
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"
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
--- /dev/null
+#!/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