From: Shane Date: Mon, 26 Jan 2026 06:17:20 +0000 (+0000) Subject: update X-Git-Url: https://git.nutra.tk/v1?a=commitdiff_plain;h=59bd5af9064cd6bfe2f3ca1a5e3bb5c7e06dce1d;p=gamesguru%2Fgit-remote-gcrypt.git update --- diff --git a/git-remote-gcrypt b/git-remote-gcrypt index 6fc12b5..8093de4 100755 --- a/git-remote-gcrypt +++ b/git-remote-gcrypt @@ -907,7 +907,28 @@ ensure_connected() isnull "$url_frag" || Manifestfile=$(xecho_n "$url_frag" | gpg_hash SHA224) else - isnull "$url_frag" || Gref_rbranch="refs/heads/$url_frag" + # not for gitception + if isnull "$url_frag"; then + if [ -z "$Did_find_repo" ] || [ "$Did_find_repo" = "no" ]; then + # Try to detect the default branch from the remote + # We only do this if we haven't found the repo (optimization/safety) + # or we can just always do it if url_frag is missing. + # `git ls-remote --symref` output looks like: + # ref: refs/heads/main HEAD + # 534... HEAD + local remote_head="" + remote_head=$(git ls-remote --symref "$URL" HEAD 2>/dev/null | grep "^ref: " | cut -f 2 -d ' ' | cut -f 1) + if isnonnull "$remote_head"; then + Gref_rbranch="$remote_head" + print_debug "Detected remote default branch: $Gref_rbranch" + echo_info "Debug: Detected remote default branch: $Gref_rbranch" + else + echo_info "Debug: Failed to detect remote default branch." + fi + fi + else + Gref_rbranch="refs/heads/$url_frag" + fi fi Repoid= @@ -1499,19 +1520,32 @@ get_remote_file_list() else # Git backend: # We need to fetch the remote state to list its files. - # Try fetching master and main to a temporary ref. - if git fetch --quiet "$URL" "refs/heads/master:refs/gcrypt/list-files" 2>/dev/null || \ - git fetch --quiet "$URL" "refs/heads/main:refs/gcrypt/list-files" 2>/dev/null; then - r_files=$(git -c core.quotePath=false ls-tree -r --name-only "refs/gcrypt/list-files") || { - git update-ref -d "refs/gcrypt/list-files" - return 1 - } - git update-ref -d "refs/gcrypt/list-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/* + 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 + local refs all_files="" ref_files="" + # distinct refs + Global_Dirty_Refs="" + refs=$(git for-each-ref --format='%(refname)' "refs/gcrypt/list-files/") + for ref in $refs; do + ref_files=$(git -c core.quotePath=false ls-tree -r --name-only "$ref") + if isnonnull "$ref_files"; then + # Map refs/gcrypt/list-files/BRANCH -> refs/heads/BRANCH + local real_ref="refs/heads/${ref#refs/gcrypt/list-files/}" + Global_Dirty_Refs="$Global_Dirty_Refs$real_ref " + all_files="$all_files$ref_files$Newline" + fi + done + + r_files=$(xecho "$all_files" | sort -u) + + # Cleanup temporary refs + git for-each-ref --format='%(refname)' "refs/gcrypt/list-files/" | \ + while read -r ref; do git update-ref -d "$ref"; done || : else # Could not fetch, or remote is empty. - # If checking, this might be fine, but for clean it's an issue if we expected files. - # Returning 1 is safer. - git update-ref -d "refs/gcrypt/list-files" 2>/dev/null || true return 1 fi fi @@ -1637,6 +1671,18 @@ cmd_clean() fi PUT_FINAL "$URL" + # Also push to any other dirty branches we found to ensure they are cleaned + if isnonnull "$Global_Dirty_Refs"; then + for ref in $Global_Dirty_Refs; do + if isnoteq "$ref" "$Gref_rbranch"; then + echo_info "Cleaning additional branch: $ref" + # Temporarily switch target branch for the push + Gref_rbranch="$ref" + PUT_FINAL "$URL" + fi + done + fi + CLEAN_FINAL "$URL" git remote remove "$NAME" 2>/dev/null || true echo_info "Done. Remote cleaned." diff --git a/tests/test-clean-all-branches.sh b/tests/test-clean-all-branches.sh new file mode 100644 index 0000000..ea04b25 --- /dev/null +++ b/tests/test-clean-all-branches.sh @@ -0,0 +1,100 @@ +#!/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 new file mode 100644 index 0000000..a017dff --- /dev/null +++ b/tests/test-clean-branch-precedence.sh @@ -0,0 +1,115 @@ +#!/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