From: Shane Date: Mon, 26 Jan 2026 06:23:45 +0000 (+0000) Subject: try this X-Git-Url: https://git.nutra.tk/v1?a=commitdiff_plain;h=5473f62546f53d2a17fe73d7f68ce7d864179792;p=gamesguru%2Fgit-remote-gcrypt.git try this --- diff --git a/git-remote-gcrypt b/git-remote-gcrypt index 8093de4..c403d17 100755 --- a/git-remote-gcrypt +++ b/git-remote-gcrypt @@ -1522,6 +1522,11 @@ get_remote_file_list() # We need to fetch the remote state to list its files. # Fetch all heads to ensure we see files on any branch (e.g. main vs master). # We map them to a temporary namespace refs/gcrypt/list-files/* + + # Clean up any stale refs/gcrypt/list-files (could be a file from old version) + # to avoid D/F conflicts with the directory we are about to use. + git update-ref -d "refs/gcrypt/list-files" 2>/dev/null || : + if git fetch --quiet "$URL" "refs/heads/*:refs/gcrypt/list-files/*" 2>/dev/null; then # List files from ALL fetched branches # We iterate refs manually to detect which one has files @@ -1650,6 +1655,16 @@ cmd_clean() echo_info "Removing files..." # If we are forcing clean on uninitialized repo, Gref might be missing. + # If we found dirty refs, pick the first one as our base to insure Gref is valid. + if [ "$Did_find_repo" != "yes" ] && isnonnull "$Global_Dirty_Refs"; then + # shellcheck disable=SC2086 + set -- $Global_Dirty_Refs + if isnonnull "$1"; then + echo_info "Using $1 as base for cleaning." + Gref_rbranch="$1" + fi + fi + # Fetch it so gitception_remove has a base. if [ "$Did_find_repo" != "yes" ] && isnonnull "$Gref_rbranch"; then git fetch -q -f "$URL" "$Gref_rbranch:$Gref" 2>/dev/null || : diff --git a/tests/test-clean-all-branches.sh b/tests/test-clean-all-branches.sh deleted file mode 100644 index ea04b25..0000000 --- a/tests/test-clean-all-branches.sh +++ /dev/null @@ -1,100 +0,0 @@ -#!/bin/bash -# Test: clean command should wipe all branches with files -set -e - -# Colors -RED='\033[0;31m' -GREEN='\033[0;32m' -CYAN='\033[0;36m' -NC='\033[0m' - -print_info() { echo -e "${CYAN}$*${NC}"; } -print_success() { echo -e "${GREEN}✓ $*${NC}"; } -print_err() { echo -e "${RED}✗ $*${NC}"; } - -# Setup path -SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)" -export PATH="$SCRIPT_DIR:$PATH" - -# Setup temp dir -tempdir=$(mktemp -d) -trap 'rm -rf "$tempdir"' EXIT - -export GNUPGHOME="${tempdir}/gpg" -mkdir -p "${GNUPGHOME}" -chmod 700 "${GNUPGHOME}" - -# GPG Wrapper -cat <<'EOF' >"${GNUPGHOME}/gpg" -#!/usr/bin/env bash -exec /usr/bin/gpg --no-tty "$@" -EOF -chmod +x "${GNUPGHOME}/gpg" - -# Helper for git -GIT="git -c advice.defaultBranchName=false -c commit.gpgSign=false" - -# Generate key -gpg --batch --passphrase "" --quick-generate-key "Test " - -# 1. Init bare repo (the "remote") -print_info "Initializing 'remote'..." -mkdir "$tempdir/remote" && cd "$tempdir/remote" -$GIT init --bare - -# 2. Populate 'main' branch with a file -print_info "Populating remote 'main' with a file..." -mkdir "$tempdir/seeder" && cd "$tempdir/seeder" -$GIT init -b main -$GIT remote add origin "$tempdir/remote" -echo "KEY DATA" >key.txt -$GIT add key.txt -$GIT config user.email "test@test.com" -$GIT config user.name "Test" -$GIT commit -m "Add key" -$GIT push origin main - -# 3. Populate 'master' branch with a file -print_info "Populating remote 'master' with a file..." -$GIT checkout -b master -echo "CONFIG DATA" >config.txt -$GIT add config.txt -$GIT commit -m "Add config" -$GIT push origin master - -# Now remote has master (config.txt) and main (key.txt + config.txt? No, branched off main). -# Both have unencrypted files. -# `clean` should remove files from both. - -# 4. Attempt clean -print_info "Attempting clean..." -cd "$tempdir" -git init -# Explicitly target the remote -if "$SCRIPT_DIR/git-remote-gcrypt" clean --init --force "gcrypt::$tempdir/remote"; then - print_info "Clean command finished." -else - print_err "Clean command failed." - exit 1 -fi - -# 5. Check if files still exist -cd "$tempdir/remote" -FAIL=0 -if $GIT -c core.quotePath=false ls-tree -r main | grep -q "key.txt"; then - print_err "FAILURE: key.txt still exists on main!" - FAIL=1 -else - print_success "SUCCESS: key.txt was removed from main." -fi - -if $GIT -c core.quotePath=false ls-tree -r master | grep -q "config.txt"; then - print_err "FAILURE: config.txt still exists on master!" - FAIL=1 -else - print_success "SUCCESS: config.txt was removed from master." -fi - -if [ $FAIL -eq 1 ]; then - exit 1 -fi diff --git a/tests/test-clean-branch-precedence.sh b/tests/test-clean-branch-precedence.sh deleted file mode 100644 index a017dff..0000000 --- a/tests/test-clean-branch-precedence.sh +++ /dev/null @@ -1,115 +0,0 @@ -#!/bin/bash -# Test: clean command fails if master exists but is empty, and files are on main -set -e - -# Colors -RED='\033[0;31m' -GREEN='\033[0;32m' -CYAN='\033[0;36m' -NC='\033[0m' - -print_info() { echo -e "${CYAN}$*${NC}"; } -print_success() { echo -e "${GREEN}✓ $*${NC}"; } -print_err() { echo -e "${RED}✗ $*${NC}"; } - -# Setup path -SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)" -export PATH="$SCRIPT_DIR:$PATH" - -# Setup temp dir -tempdir=$(mktemp -d) -trap 'rm -rf "$tempdir"' EXIT - -export GNUPGHOME="${tempdir}/gpg" -mkdir -p "${GNUPGHOME}" -chmod 700 "${GNUPGHOME}" - -# GPG Wrapper -cat <<'EOF' >"${GNUPGHOME}/gpg" -#!/usr/bin/env bash -exec /usr/bin/gpg --no-tty "$@" -EOF -chmod +x "${GNUPGHOME}/gpg" - -# Helper for git -GIT="git -c advice.defaultBranchName=false -c commit.gpgSign=false" - -# Generate key -gpg --batch --passphrase "" --quick-generate-key "Test " - -# 1. Init bare repo (the "remote") -print_info "Initializing 'remote'..." -mkdir "$tempdir/remote" && cd "$tempdir/remote" -$GIT init --bare - -# 2. Populate 'main' branch with a file -print_info "Populating remote 'main' with a file..." -mkdir "$tempdir/seeder_main" && cd "$tempdir/seeder_main" -$GIT init -b main -$GIT remote add origin "$tempdir/remote" -echo "SECRET DATA" >secret.txt -$GIT add secret.txt -$GIT config user.email "test@test.com" -$GIT config user.name "Test" -$GIT commit -m "Add secret" -$GIT push origin main - -# 3. Create an empty 'master' branch on the remote using a second seeder -# We do this by pushing an unrelated history or just a new branch -print_info "Creating empty 'master' on remote..." -mkdir "$tempdir/seeder_master" && cd "$tempdir/seeder_master" -$GIT init -b master -$GIT remote add origin "$tempdir/remote" -touch empty.txt -$GIT add empty.txt -$GIT config user.email "test@test.com" -$GIT config user.name "Test" -$GIT commit -m "Add empty" -$GIT push origin master - -# Now remote has both master (with empty.txt) and main (with secret.txt) -# But wait, if master has empty.txt, `clean` should at least find empty.txt. -# We want to simulate a case where `master` is "empty" or irrelevant, but `main` is the real one. -# If `master` has files, `clean` will report them. -# The user said: "Remote is empty. Nothing to clean." -# This implies `master` has NO files? -# How can a branch exist but have no files? -# Maybe `git ls-tree -r master` returns nothing if the branch is truly empty (e.g. only contains a .gitignore that was filtered out, or maybe just literally empty tree - possible in git but hard to maximize). -# Or maybe the user has `master` that is just NOT the one with the data. -# The user's output "Remote is empty" suggests `clean` found NOTHING. -# If `master` had `empty.txt`, `clean` would list `empty.txt`. - -# Let's clean up `master` to be truly empty? -# GIT allows empty commits but they still have a tree. -# If we delete all files from master? -cd "$tempdir/seeder_master" -$GIT rm empty.txt -$GIT commit -m "Remove all" -$GIT push origin master - -# Now master exists but has NO files. "secret.txt" is on main. -# `clean` should ideally check `main` (or all branches) and find `secret.txt`. -# If `clean` only checks `master`, it will see empty tree and say "Remote is clean". - -# 4. Attempt clean -print_info "Attempting clean..." -cd "$tempdir" -git init -# Explicitly target the remote -if "$SCRIPT_DIR/git-remote-gcrypt" clean --init --force "gcrypt::$tempdir/remote"; then - print_info "Clean command finished." -else - print_err "Clean command failed." - exit 1 -fi - -# 5. Check if secret.txt is still there -cd "$tempdir/remote" -if $GIT -c core.quotePath=false ls-tree -r main | grep -q "secret.txt"; then - print_err "FAILURE: secret.txt still exists on main!" - exit 1 -else - print_success "SUCCESS: secret.txt was removed (or wasn't there)." - # If it wasn't there, we need to know if we actually cleaned it. - # The clean output should have mentioned it. -fi diff --git a/tests/test-clean-ref-conflict.sh b/tests/test-clean-ref-conflict.sh new file mode 100644 index 0000000..27350ba --- /dev/null +++ b/tests/test-clean-ref-conflict.sh @@ -0,0 +1,66 @@ +#!/bin/bash +# Test: clean command fails if refs/gcrypt/list-files exists as a file (D/F conflict) +set -e +RED='\033[0;31m' +GREEN='\033[0;32m' +NC='\033[0m' +print_info() { echo -e "${GREEN}$*${NC}"; } +print_err() { echo -e "${RED}✗ $*${NC}"; } + +SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)" +export PATH="$SCRIPT_DIR:$PATH" +tempdir=$(mktemp -d) +trap 'rm -rf "$tempdir"' EXIT + +export GNUPGHOME="${tempdir}/gpg" +mkdir -p "${GNUPGHOME}" +chmod 700 "${GNUPGHOME}" +cat <<'EOF' >"${GNUPGHOME}/gpg" +#!/usr/bin/env bash +exec /usr/bin/gpg --no-tty "$@" +EOF +chmod +x "${GNUPGHOME}/gpg" + +GIT="git -c advice.defaultBranchName=false -c commit.gpgSign=false" +gpg --batch --passphrase "" --quick-generate-key "Test " + +mkdir "$tempdir/remote" && cd "$tempdir/remote" +$GIT init --bare + +mkdir "$tempdir/seeder" && cd "$tempdir/seeder" +$GIT init -b main +$GIT remote add origin "$tempdir/remote" +echo "DATA" >file.txt +$GIT add file.txt +$GIT commit -m "init" +$GIT push origin main + +print_info "Attempting clean with poisoned environment..." +cd "$tempdir" +git init +# Create a commit so we have something to point the ref to +touch foo +git add foo +git commit -m "init" + +# POISON: Create a ref that conflicts with the directory we want to use +# The old code used refs/gcrypt/list-files as a file. +# The new code uses refs/gcrypt/list-files/BRANCH. +# If we have the old ref, git fetch might fail. +git update-ref refs/gcrypt/list-files HEAD + +if "$SCRIPT_DIR/git-remote-gcrypt" clean --init --force "gcrypt::$tempdir/remote"; then + print_info "Clean command finished." +else + print_err "Clean command returned error code." +fi + +# Check if file still exists (it should be gone if clean worked) +cd "$tempdir/remote" +files=$($GIT ls-tree -r main | grep "file.txt" || :) +if [ -n "$files" ]; then + print_err "FAILURE: file.txt still exists on main! (Clean likely failed silently)" + exit 1 +else + print_info "SUCCESS: file.txt was removed." +fi