From 442db6a664bdddd32bf725bc5121c737951d450d Mon Sep 17 00:00:00 2001 From: cproudlock Date: Sun, 30 Aug 2026 09:04:56 -0400 Subject: [PATCH] Mirror the publication branch BEFORE the sync, not after The branch checkout landed after the rsync, where git checkout --force reverts the tree to the branch's committed state and discards everything rsync had just written. The export then found no changes and published nothing, while still printing a bundle path and looking like it had worked. A silent no-op is the worst shape for this: the next person believes the export ran. Scope: product (cherry picked from commit 06c584240ee3439d90f0968afb5c2e2370bbdb74) --- tools/export-github.sh | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/tools/export-github.sh b/tools/export-github.sh index 0a99e084..cbcb788f 100755 --- a/tools/export-github.sh +++ b/tools/export-github.sh @@ -98,6 +98,29 @@ done # Keep flags on their own lines. A comment inside this backslash-continued # command is not a comment - bash hands the text to rsync as arguments, and it # dies with a usage dump rather than anything that names the real problem. +# Mirror the branch in the publication repo BEFORE the sync. +# +# Order matters and got this wrong once: done after the rsync, `git checkout +# --force` reverts the tree to the branch's committed state and throws away +# everything rsync just wrote, so the export reports "no changes" and publishes +# nothing. It is a silent no-op, which is the worst shape for this failure - +# the script still prints a bundle path and looks like it worked. +# +# --force is needed because the tree may hold leftovers from the previously +# published branch, and safe because this tree is a mirror: the rsync below +# replaces it wholesale from $WORK. +( + cd "$PUB" + if git show-ref --verify --quiet "refs/heads/$BRANCH"; then + git checkout --force "$BRANCH" >/dev/null + else + # A new site branch starts from main, as it does in the dev repo, so its + # history is the product's plus whatever it adds. + echo "==> publication repo: creating branch $BRANCH from main" + git checkout --force -b "$BRANCH" main >/dev/null + fi +) + rsync -a --delete \ --exclude '.git' \ --exclude '.gitea' \ @@ -157,19 +180,6 @@ fi cd "$PUB" -# Mirror the branch. The rsync above has already overwritten the tree, so this -# has to happen with the working tree ignored - checkout would otherwise refuse -# or clobber. --force is safe here precisely because the tree is a mirror: it -# holds nothing that is not about to be replaced from $WORK. -if git show-ref --verify --quiet "refs/heads/$BRANCH"; then - git checkout --force "$BRANCH" >/dev/null -else - # A new site branch starts from main, the same way it does in the dev repo, - # so its history is the product's history plus whatever it adds. - echo "==> publication repo: creating branch $BRANCH from main" - git checkout --force -b "$BRANCH" main >/dev/null -fi - # --- 2. re-apply the publication wording (idempotent) --- # docs/ lives only in the wiki on the GitHub side. # NOTE the `|| true` on each scrub grep below. grep exits 1 when it matches