From: Shane Jaroch Date: Sat, 17 Jan 2026 03:45:34 +0000 (-0500) Subject: wip X-Git-Url: https://git.nutra.tk/v1?a=commitdiff_plain;h=e36c51856383e35f45063e6a98193a5f0f056fdb;p=gamesguru%2Fgit-remote-gcrypt.git wip --- diff --git a/completions/gen_docs.sh b/completions/gen_docs.sh index 23277e8..93b2a92 100755 --- a/completions/gen_docs.sh +++ b/completions/gen_docs.sh @@ -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" diff --git a/git-remote-gcrypt b/git-remote-gcrypt index 97bcc8b..74c2a58 100755 --- a/git-remote-gcrypt +++ b/git-remote-gcrypt @@ -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 index 0000000..13100db --- /dev/null +++ b/tests/manual_test_clean_local.sh @@ -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 <"${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 " + +# 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