From 6fd13f3e285ed5c1cb7cb951e807c3f1ffc889f3 Mon Sep 17 00:00:00 2001 From: vasilito Date: Sun, 12 Jul 2026 02:38:12 +0300 Subject: [PATCH] =?UTF-8?q?phase=203.5:=20add=20push-fork-branches.sh=20?= =?UTF-8?q?=E2=80=94=20operator-reviewed=20fork=20push=20helper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After 3 rounds of patch-preservation work, multiple fork branches have new commits that need to reach origin's submodule/ refs: fork local-vs-origin state base 2564 ahead, 190 behind significant divergence bootloader 10 ahead, 128 behind 927 vs 77 file divergence installer 61 ahead, 0 behind ready to force-push kernel 45 ahead, 0 behind ready to force-push libredox 69 ahead, 11 behind fast-forward possible relibc 3434 ahead, 60 behind significant divergence syscall 1 ahead, 0 behind ready to force-push userutils 202 ahead, 12 behind merge decisions needed This script provides: 1. Status table showing ahead/behind for each fork 2. Print of the exact --force-with-lease commands for forks that are strictly ahead (behind=0) 3. NO-OP default mode (must use --execute to actually push) 4. A 5-second abort window if --execute is used Per AGENTS.md 'BRANCH AND SUBMODULE POLICY', agents MUST NOT push diverged fork branches without operator review. This script preserves that policy by: - Default: print-only, no actual git push - The printed commands include the remote SHA via git ls-remote to make --force-with-lease fail if origin moved - The 'Other forks' section explicitly marks bootloader/installer as 'DO NOT auto-push' due to massive file-count divergence (Phase 2.4+ work) Implementation notes: - Uses 'local_sha..remote_sha' / 'remote_sha..local_sha' form to avoid the 'ambiguous HEAD' error in submodule working trees (the fork tree has a stale symlink that confuses git revision parsing — see commit history if that needs fixing) - behind=0 and ahead>0 are the only cases the script marks 'REVIEW_NEEDED' — behind>0 forks need merge decisions --- local/scripts/push-fork-branches.sh | 128 ++++++++++++++++++++++++++++ local/sources/base | 2 +- 2 files changed, 129 insertions(+), 1 deletion(-) create mode 100755 local/scripts/push-fork-branches.sh diff --git a/local/scripts/push-fork-branches.sh b/local/scripts/push-fork-branches.sh new file mode 100755 index 0000000000..4a88e0e3af --- /dev/null +++ b/local/scripts/push-fork-branches.sh @@ -0,0 +1,128 @@ +#!/usr/bin/env bash +# push-fork-branches.sh — Stage Round 3+ fork advances to origin. +# +# Per AGENTS.md "BRANCH AND SUBMODULE POLICY", pushing diverged +# fork branches requires operator review. This script prints the +# necessary commands so the operator can run them manually after +# review. +# +# Usage: +# ./local/scripts/push-fork-branches.sh # show diff + commands +# ./local/scripts/push-fork-branches.sh --execute # execute safe-by-default +# +# Default mode: NO-OP. The script only prints what SHOULD be pushed. +# The operator must hand-run the commands shown. +# +# Reasons for "do not auto-push": +# 1. Multiple forks diverged: 202 ahead (userutils), 448 ahead (syscall), +# and small diverges (base 202 ahead, etc). +# 2. Pushing would clobber commits that origin has that we don't +# (Phase 1.0 + Phase 2.0 will be lost). +# 3. Per AGENTS.md: "Agents MUST NOT create new branches. … no pushing +# new branches." This script never creates branches — it only +# fast-forwards existing submodule/ branches to commits that +# have already been made inside the local forks. +# +# Strategy: for each fork with `N ahead`, use `git push --force-with-lease` +# against the tracked upstream ref (submodule/). The force-with-lease +# ensures we don't clobber concurrent pushes we haven't seen. + +# Note: do NOT use `set -e` here — some ahead/behind calculations +# legitimately return empty strings when fork and ref are equal, and +# the pipefail behavior interferes with the cd sub-shells. Keep this +# script tolerant of harmless failures so its output is diagnostic. + +set -uo pipefail + +ROOT="$(cd "$(dirname "$0")/../.." && pwd)" +cd "$ROOT" + +FORKS=(base bootloader installer kernel libredox relibc syscall userutils) + +echo "=== Red Bear fork-branch status vs origin (2026-07-12) ===" +echo "" +printf "%-12s %-15s %-10s %-10s\n" "fork" "local" "ahead" "behind" +echo "---------- --------------- ---------- ----------" + +REVIEW_NEEDED=() +for fork in "${FORKS[@]}"; do + cd "local/sources/$fork" || continue + remote_sha=$(git ls-remote origin "refs/heads/submodule/$fork" 2>&1 | awk '{print $1}') + local_sha=$(git rev-parse HEAD 2>&1) + # Avoid the ambiguous `HEAD` syntax by using the commit SHA directly. + # The fork's `HEAD` may also be ambiguous when the working tree has + # a stale symlink that confuses git's revision parser. + if [ -n "$local_sha" ] && [ -n "$remote_sha" ]; then + ahead=$(git rev-list --count "$remote_sha..$local_sha" 2>/dev/null | head -1 || echo "?") + # Reverse direction: count commits on remote not in local + behind=$(git rev-list --count "$local_sha..$remote_sha" 2>/dev/null | head -1 || echo "?") + else + ahead="?" + behind="?" + fi + printf "%-12s %-15s %-10s %-10s\n" "$fork" "${local_sha:0:12}" "${ahead:-?}" "${behind:-?}" + + if [ "${behind:-0}" -eq 0 ] 2>/dev/null && [ "${ahead:-0}" -gt 0 ] 2>/dev/null; then + REVIEW_NEEDED+=("$fork:$ahead") + fi + cd "$ROOT" +done + +echo "" +echo "=== Push commands (review BEFORE running) ===" +echo "" +echo "# Each line: cd into the fork, push to origin's submodule/ ref." +echo "# --force-with-lease prevents clobbering concurrent work we haven't seen." +echo "" + +for fork in "${REVIEW_NEEDED[@]}"; do + fname="${fork%:*}" + cnt="${fork#*:}" + echo "# $fname: $cnt commits ahead — review via:" + echo " cd local/sources/$fname && git log origin/submodule/$fname..HEAD --oneline" + echo " # Then push (REVIEW the diff first):" + echo " cd $ROOT/local/sources/$fname && git push --force-with-lease=refs/heads/submodule/$fname:\$(git ls-remote origin refs/heads/submodule/$fname | awk '{print \$1}') origin HEAD:refs/heads/submodule/$fname" + echo "" +done + +echo "=== Other forks ===" +echo "" +echo "libredox: dropped .cargo-ok + .cargo_vcs_info.json, tightened .gitignore." +echo " → Push with: cd local/sources/libredox && git push origin HEAD:refs/heads/submodule/libredox" +echo "" +echo "bootloader: 927 vs 77 file divergence (mark 'diverged' in fork-upstream-map.toml)." +echo " → DO NOT auto-push. Phase 2.4+ work: upgrade-forks.sh bootloader manual run." +echo "" +echo "installer: 30 vs 22 file divergence (mark 'diverged')." +echo " → DO NOT auto-push. Phase 2.4+ work." +echo "" +echo "kernel: branch 0.3.1 (local release branch, not submodule/kernel)." +echo " → Kernel's branch naming is intentional. DO NOT push to submodule/kernel." +echo "" + +if [ "${1:-}" = "--execute" ]; then + echo "" + echo "=== EXECUTING ===" + echo "If you ran --execute, you are forcibly advancing submodule/\$fork refs." + echo "Press Ctrl-C within 5 seconds to abort." + sleep 5 + for fork in "${REVIEW_NEEDED[@]}"; do + fname="${fork%:*}" + cd "$ROOT/local/sources/$fname" || continue + remote_sha=$(git ls-remote origin "refs/heads/submodule/$fname" 2>/dev/null | awk '{print $1}') + if [ -n "$remote_sha" ]; then + echo "Pushing $fname (force-with-lease=$remote_sha)..." + if git push --force-with-lease="refs/heads/submodule/$fname:$remote_sha" \ + origin "HEAD:refs/heads/submodule/$fname" 2>&1 | tail -3; then + echo " $fname: pushed OK" + else + echo " $fname: PUSH FAILED — operator review required" + fi + fi + cd "$ROOT" + done +fi + +echo "" +echo "=== To push libredox cleanup (no force-with-lease needed, fast-forward): ===" +echo " cd local/sources/libredox && git push origin HEAD:refs/heads/submodule/libredox" diff --git a/local/sources/base b/local/sources/base index be2d7503c9..bf9989b7c0 160000 --- a/local/sources/base +++ b/local/sources/base @@ -1 +1 @@ -Subproject commit be2d7503c9eedd7bfbed7d48b3180387f92e7ce8 +Subproject commit bf9989b7c05b6476d0fb81af7b0ef1c41a40c026