From b042c2583ed61cac4bd0bb0f720d43dcd60829d1 Mon Sep 17 00:00:00 2001 From: Shane Jaroch Date: Mon, 26 Jan 2026 00:54:16 -0500 Subject: [PATCH] stat updates? idk? strict? --- README.rst | 12 ++++ git-remote-gcrypt | 11 +++- tests/system-test.sh | 35 ++++++++++ tests/test-safety-check-repro.sh | 106 +++++++++++++++++++++++++++++++ 4 files changed, 162 insertions(+), 2 deletions(-) create mode 100755 tests/test-safety-check-repro.sh diff --git a/README.rst b/README.rst index e9dcabd..dad1741 100644 --- a/README.rst +++ b/README.rst @@ -317,6 +317,18 @@ unencrypted files, you must use the ``--force`` flag:: git-remote-gcrypt clean url --force + +Stats for gcrypt repos +====================== + +To show diagnostics for a remote gcrypt repo, use:: + + git-remote-gcrypt stat [url|remote] + +This command will list the total number of files on the remote, and if +a valid gcrypt repository is detected, it will also show the number of +tracked (encrypted) files versus untracked (plain) files. + Known issues ============ diff --git a/git-remote-gcrypt b/git-remote-gcrypt index bc9d938..b438669 100755 --- a/git-remote-gcrypt +++ b/git-remote-gcrypt @@ -928,6 +928,10 @@ ensure_connected() echo_info "..but repository ID is set. Aborting." return 1 else + if [ "$1" = "strict" ]; then + echo_info "Repository not found: $URL" + return 1 + fi echo_info "Repository not found: $URL" return 0 fi @@ -1093,7 +1097,7 @@ do_capabilities() do_list() { local obj_id="" ref_name="" line_="" - ensure_connected + ensure_connected "$1" xecho "$Refslist" | while read -r line_ do @@ -1423,7 +1427,10 @@ gcrypt_main_loop() capabilities) do_capabilities ;; - list|list\ for-push) + list) + do_list strict + ;; + list\ for-push) do_list ;; fetch\ *) diff --git a/tests/system-test.sh b/tests/system-test.sh index 11c763c..067c254 100755 --- a/tests/system-test.sh +++ b/tests/system-test.sh @@ -531,3 +531,38 @@ if [ -n "${COV_DIR:-}" ]; then print_success "OK. Report: file://${COV_DIR}/index.html" fi +### +section_break + +print_info "Step 11: Stat Command Test:" +{ + cd "${tempdir}/first" + + # Run stat on the valid repo (second.git) + output_file="${tempdir}/stat_output" + print_info "Running stat on valid repo (second.git)..." + ( + set -x + git-remote-gcrypt stat "gcrypt::${tempdir}/second.git#${default_branch}" + ) > "${output_file}" 2>&1 + + # Display output for debugging + indent < "${output_file}" + + # Verify expected output strings + if grep -q "Total files:" "${output_file}" && \ + grep -q "Gcrypt repository: detected" "${output_file}" && \ + grep -q "Tracked/Encrypted files:" "${output_file}"; then + print_success "Stat command output verified." + else + print_err "Stat command missing expected output!" + grep "Total" "${output_file}" || echo "Total not found" + grep "Gcrypt" "${output_file}" || echo "Gcrypt detected not found" + grep "Tracked" "${output_file}" || echo "Tracked not found" + exit 1 + fi + +} | indent + + + diff --git a/tests/test-safety-check-repro.sh b/tests/test-safety-check-repro.sh new file mode 100755 index 0000000..2fb8f5c --- /dev/null +++ b/tests/test-safety-check-repro.sh @@ -0,0 +1,106 @@ +#!/bin/bash +# Test: Safety check aborts on standard git files (HEAD, config, etc) +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 -c init.defaultBranch=master" + +# Generate key +gpg --batch --passphrase "" --quick-generate-key "Test " +KEYID=$(gpg --list-keys --with-colons "test@test.com" | awk -F: '/^pub:/ { print $5 }') + +# 1. Init bare repo as "remote" (creates HEAD, config, description, etc) +print_info "Initializing 'remote' as standard bare repo..." +mkdir "$tempdir/remote" && cd "$tempdir/remote" +$GIT init --bare + +# 2. Try to clone/push using gcrypt +print_info "Attempting check/stat from gcrypt..." +cd "$tempdir" +mkdir client && cd client +$GIT init +$GIT config user.email "test@test.com" +$GIT config user.name "Test" + +# We use 'stat' because it triggers early_safety_check +# Use rsync to trigger the dumb backend logic +# rsync needs ssh, might be complex in restricted env. +# Let's mock rsync instead? +# Or just use the fact that 'islocalrepo' check failed because of HEAD. +# 'islocalrepo' is: isnull "${1##/*}" && [ ! -e "$1/HEAD" ] +# The user has HEAD on the remote. rsync doesn't check HEAD locally. +# If we used rsync://, 'islocalrepo' wouldn't run. + +# Mock rsync command to list files? +# The script calls: rsync --no-motd --list-only ... +# If we override rsync function... + +# Better: Just pretend to be sftp or rsync by overriding checks? No. + +# Mock rsync command to list files? +# The script calls: rsync --no-motd --list-only ... + +# We create a fake 'rsync' in a temp bin dir +mkdir -p "$tempdir/bin" +cat <"$tempdir/bin/rsync" +#!/bin/bash +# Mock rsync listing +if echo "\$@" | grep -q "list-only"; then + echo "DEBUG: Mock rsync listing contents of $tempdir/remote" >&2 + # Simulate rsync output format: drwxr-xr-x 4096 2023/01/01 00:00:00 . + # But strictly speaking we just need the filename at the end. + for f in \$(ls -1 "$tempdir/remote"); do + echo "-rw-r--r-- 1024 2023/01/01 00:00:00 \$f" + done +else + # Fallback or error + echo "Mock rsync called with: \$@" >&2 + exit 0 +fi +EOF +chmod +x "$tempdir/bin/rsync" +export PATH="$tempdir/bin:$PATH" + +# Use a dummy host for rsync, as we are mocking the binary +if "$SCRIPT_DIR/git-remote-gcrypt" stat "gcrypt::rsync://mock/$tempdir/remote" >"$tempdir/output" 2>&1; then + + cat "$tempdir/output" + if grep -q "Found unexpected files: HEAD config" "$tempdir/output"; then + print_success "Caught safety violation correctly." + else + print_err "Failed but wrong message?" + exit 1 + fi +else + print_err "Safety check passed unexpectedly!" + exit 1 +fi -- 2.52.0