]> Nutra Git (v2) - gamesguru/git-remote-gcrypt.git/commitdiff
update
authorShane <chown_tee@proton.me>
Mon, 26 Jan 2026 06:17:20 +0000 (06:17 +0000)
committerShane <chown_tee@proton.me>
Mon, 26 Jan 2026 06:17:20 +0000 (06:17 +0000)
git-remote-gcrypt
tests/test-clean-all-branches.sh [new file with mode: 0644]
tests/test-clean-branch-precedence.sh [new file with mode: 0644]

index 6fc12b53929a4a3360292e0ea785ca03c249f882..8093de441ec5ac98a8ae1451e356200a40b9db26 100755 (executable)
@@ -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 (file)
index 0000000..ea04b25
--- /dev/null
@@ -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 <test@test.com>"
+
+# 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 (file)
index 0000000..a017dff
--- /dev/null
@@ -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 <test@test.com>"
+
+# 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