#!/usr/bin/env bash # unblock-base-push.sh — Operator-side fix for base fork push deadlock # # Round 5/6 of patch-preservation work left the base fork unable to # be force-pushed to origin via standard git operations. The cause: # gitea's `receive.shallowUpdate=true` config (server-side default # for shallow-cloned submodule refs) refuses any push that would # deepen the ref. # # Per AGENTS.md "BRANCH AND SUBMODULE POLICY", agents cannot disable # server-side policies or create new branches. This script provides # the OPERATOR with 3 documented paths to unblock the base push. # # Usage: # ./local/scripts/unblock-base-push.sh path-a # Show option A # ./local/scripts/unblock-base-push.sh path-b # Show option B # ./local/scripts/unblock-base-push.sh path-c # Show option C # ./local/scripts/unblock-base-push.sh info # Show current state # # Round 5 of patch work is unsafe to re-attempt without operator # unblock. Until then, the operator can verify the local fork # state via: # cd local/sources/base && git log --oneline -10 set -euo pipefail ROOT="$(cd "$(dirname "$0")/../.." && pwd)" cd "$ROOT" cd "local/sources/base" 2>/dev/null || true print_state() { cd "$ROOT/local/sources/base" 2>/dev/null || { echo "ERROR: base fork not at $ROOT/local/sources/base"; return 1; } cat << 'EOF' === base fork current state === EOF echo " local SHA: $(git rev-parse HEAD 2>/dev/null)" local remote_sha=$(git ls-remote origin refs/heads/submodule/base 2>/dev/null | awk '{print $1}') echo " remote SHA: ${remote_sha:-(not found)}" local ahead=$(git rev-list --count "refs/heads/submodule/base..HEAD" 2>/dev/null) local behind=$(git rev-list --count "HEAD..refs/heads/submodule/base" 2>/dev/null) echo " ahead: $ahead ahead / $behind behind" echo " last 5 local commits:" git log --oneline -5 2>/dev/null cd "$ROOT" } print_path_a() { cat << 'EOF' === Path A: gitea admin shell (operator-only) === 1. SSH to the gitea host: ssh operator@gitea.redbearos.org 2. Open gitea admin CLI: gitea admin 3. List available repo options: gitea admin repo-list 4. Set receive.shallowUpdate = false on the RedBear-OS repo: gitea admin repo-edit --receive.shallowUpdate=false vasilito/RedBear-OS # Or update config.toml directly: # [repo.vasilito/RedBear-OS] # RECEIVE_SHALLOW_UPDATE = false 5. Verify change: gitea admin repo-list | grep -i redbearos 6. Push from local clone: cd /path/to/RedBear-OS ./local/scripts/push-fork-branches.sh --execute This is the recommended path. The change is per-repo, doesn't affect other gitea repos, and is reversible. EOF } print_path_b() { cat << 'EOF' === Path B: gitea web UI (no admin needed) === 1. Open the gitea web UI: https://gitea.redbearos.org/vasilito/RedBear-OS 2. Navigate to "Settings" → "Branches" (or "Repository" → "Branches") 3. For submodule/base branch: - Click "Edit" or "Settings" - In "Push options" or "Receive options" section, uncheck "Block new pushes that would result in a non-fast-forward" (or similar wording depending on gitea version) - Save 4. The exact option name varies by gitea version. Common names: - "receive.shallowUpdate = false" - "Allow non-fast-forward updates" - "Disable shallow update protection" 5. After saving, push from local clone: cd /path/to/RedBear-OS ./local/scripts/push-fork-branches.sh --execute This path is convenient when SSH access is not available but the operator has web UI admin access. EOF } print_path_c() { cat << 'EOF' === Path C: server-side hook (advanced; operator-only) === 1. SSH to gitea host. 2. Find gitea's repo hooks directory (typical paths: /var/lib/gitea/custom/hooks/ or similar) 3. Create a pre-receive hook that: a. Reads the incoming ref b. If ref is submodule/base, force-update the ref c. Update the bare repo's submodule/base ref to match the new SHA 4. Restart gitea to load the hook Or simpler: as gitea admin, run: gitea admin repo-update --receive.shallowUpdate=false vasilito/RedBear-OS This is the most invasive path. Recommended only when A and B are not feasible. EOF } case "${1:-info}" in path-a) print_path_a ;; path-b) print_path_b ;; path-c) print_path_c ;; info|state|'') print_state ;; *) echo "Unknown: $1" >&2; exit 1 ;; esac