fix two bugs with push/clean exiting cowardly
authorShane Jaroch <chown_tee@proton.me>
Tue, 13 Jan 2026 21:50:37 +0000 (16:50 -0500)
committerShane Jaroch <chown_tee@proton.me>
Tue, 13 Jan 2026 22:09:22 +0000 (17:09 -0500)
Makefile
TODO.rst
git-remote-gcrypt
tests/test_rsync_simple.sh [new file with mode: 0644]

index 8d2a012196aca2fa681085b095591e27857beeca..8ddfcc76218c740caf0bc4325797766a32b31fe2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -212,6 +212,21 @@ uninstall/user:    ##H make uninstall prefix=~/.local
 
 
 
+
+.PHONY: deploy/debian
+deploy/debian: ##H Build Debian package
+       @$(call print_target,deploy/debian)
+       @$(call print_info,Building Debian package...)
+       gbp buildpackage -uc -us
+       @$(call print_success,Built Debian package.)
+
+.PHONY: deploy/redhat
+deploy/redhat: ##H Build RPM package
+       @$(call print_target,deploy/redhat)
+       @$(call print_info,Building RPM package...)
+       rpmbuild -bb redhat/git-remote-gcrypt.spec
+       @$(call print_success,Built RPM package.)
+
 .PHONY: clean
 clean: ##H Clean up
        rm -rf .coverage .build_tmp
index f22980eac2a8e894d3d5c49b3eecadffde1cab1a..d1afd10b93d8bca439a1d8d3a4a05818c660ce73 100644 (file)
--- a/TODO.rst
+++ b/TODO.rst
@@ -1,7 +1,9 @@
 
 Saturday, 1/10/26
 
-Q: Does the manifest
+Q: Does the manifest... (contain? <incomplete>)
+
+~~~~~~~~~~~~~~~~~~~~~~
 
 The issue here is the second one is a valid, encrypted remote.
 The tool is doing too much work and providing dumb results, at times, by trying to be fancy and smart.
index be58d0ce0cb6d7f2c533a18bbc62abcd2d2399c5..951d7c250ccb4b3ccab6e3da73aa56475073e4a1 100755 (executable)
@@ -520,8 +520,15 @@ REMOVE()
                print_debug "Calling rsync..."
                (
                        if [ -n "${GCRYPT_TRACE:-}" ]; then set -x; fi
+                       # rsync needs parent directories included or it won't traverse them
+                       echo "$2" | while IFS= read -r f; do
+                               d=$(dirname "$f")
+                               mkdir -p "$Localdir/$d"
+                       done
+
                        # rsync needs stdin for --include-from=-
-                       rsync -I -W -v -r --delete --include-from=- \
+                       # We include specific files ($2), then include ALL directories (*/), then exclude everything else (*).
+                       rsync -I -W -v -r --delete --include-from=- --include='*/' \
                        --exclude='*' "$Localdir"/ "$(rsynclocation "$1")/" >&2
                ) <<EOF
 $2
@@ -750,18 +757,21 @@ early_safety_check()
                if isnull "$dumb_files"; then
                        return 0
                fi
-               
+
+               early_bad_files=$(echo "$dumb_files" | grep -v -E '^[a-f0-9]{56}$|^[a-f0-9]{64}$|^[a-f0-9]{96}$|^[a-f0-9]{128}$' || :)
+               if isnull "$early_bad_files"; then
+                       return 0
+               fi
+
                if [ "$(git config --bool gcrypt.allow-unencrypted-remote)" = "true" ]; then
                        return 0
                fi
 
-               echo_info "ERROR: Remote repository is not empty!"
-               echo_info "To protect your privacy, git-remote-gcrypt will NOT push to this remote"
-               echo_info "unless you force it or clean it."
-               echo_info "Found files: $(echo "$dumb_files" | head -n 3 | tr '\n' ' ')..."
-               echo_info "To see files: git-remote-gcrypt clean $URL"
-               echo_info "To init anyway (DANGEROUS if not empty): git push --force ..."
-               echo_info "OR set gcrypt.allow-unencrypted-remote to true."
+               echo_info "ERROR: Remote repository contains unencrypted or unknown files!"
+               echo_info "To protect your privacy, git-remote-gcrypt will NOT push to this remote."
+               echo_info "Found unexpected files: $(echo "$early_bad_files" | head -n 3 | tr '\n' ' ')"
+               echo_info "To see unencrypted files, use: git-remote-gcrypt clean $URL"
+               echo_info "To fix and remove these files, use: git-remote-gcrypt clean --force $URL"
                exit 1
        fi
 
diff --git a/tests/test_rsync_simple.sh b/tests/test_rsync_simple.sh
new file mode 100644 (file)
index 0000000..c6e1d34
--- /dev/null
@@ -0,0 +1,39 @@
+#!/bin/bash
+set -e
+mkdir -p .tmp/simple_src .tmp/simple_dst/subdir
+touch .tmp/simple_dst/subdir/badfile
+touch .tmp/simple_dst/subdir/goodfile
+
+files_to_remove="subdir/badfile"
+Localdir=".tmp/simple_src"
+
+# 1. Recreate directory structure in source
+echo "$files_to_remove" | xargs -n1 dirname | sort -u | while read -r d; do
+       mkdir -p "$Localdir/$d"
+done
+
+# 2. Run rsync with --include='*/' to traverse all dirs, but specific file includes
+# Note: --include='*/' must come BEFORE --exclude='*'
+# And we also need to include our specific files.
+# Order:
+# Include specific files
+# Include all directories (so we traverse)
+# Exclude everything else
+
+echo "Running rsync..."
+rsync -I -W -v -r --delete --include-from=- --include='*/' --exclude='*' "$Localdir"/ .tmp/simple_dst/ <<EOF
+$files_to_remove
+EOF
+
+echo "Checking results..."
+if [ -e .tmp/simple_dst/subdir/badfile ]; then
+       echo "FAIL: badfile NOT removed"
+else
+       echo "SUCCESS: badfile removed"
+fi
+
+if [ ! -e .tmp/simple_dst/subdir/goodfile ]; then
+       echo "FAIL: goodfile was INCORRECTLY removed"
+else
+       echo "SUCCESS: goodfile preserved"
+fi