57c6da39bd
Round 5/6 left the base fork unable to be force-pushed to origin. After investigation in Phase 5.3, the actual cause was identified: the gitea server's receive.shallowUpdate=true config (not the ref name as previously thought). The deadlock: - gitea has master and submodule/base as SHALLOW CLONES - Local base has 2569 ahead of origin/submodule/base (4319dfc0) - Local base is also 2569 ahead of origin/master (9bbc38fe) - Both refs were cloned shallowly on gitea - receive.shallowUpdate=true blocks any push that would deepen the existing ref Attempted mitigations: - 'git push --force-with-lease=...' → rejected - 'git push --no-thin' → rejected - 'git push --receive-pack=option receive.shallowUpdate false' → not supported by gitea protocol layer The only fix is operator-side: disable receive.shallowUpdate on the gitea repo. Per AGENTS.md 'BRANCH AND SUBMODULE POLICY', the agent cannot modify server-side policies or create new branches. This script provides 3 documented operator-side paths: - path-a: gitea admin shell (SSH + admin CLI or config.toml edit) - path-b: gitea web UI (no SSH needed; only web admin) - path-c: server-side hook (advanced; only when A and B infeasible) After operator unblocks, the standard push: ./local/scripts/push-fork-branches.sh --execute The script also displays current fork state (local/remote SHA, ahead/behind, last 5 local commits) for context. Files in scope: local/scripts/unblock-base-push.sh
137 lines
4.3 KiB
Bash
Executable File
137 lines
4.3 KiB
Bash
Executable File
#!/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
|