From 185a044c5eb54c6aec2cafeeda5a7ae023682077 Mon Sep 17 00:00:00 2001 From: Tobi G Date: Mon, 7 Sep 2026 20:58:05 +0200 Subject: [PATCH] Signierskript: ein Klon von vor dem Rewrite darf nicht pullen Am 07.09.2026 sind drei Commits am Ende von main entfernt und der Branch per Force-Push zurueckgesetzt worden. Ein aelterer Klon - der Mac, auf dem signiert wird - steht damit VORAUS statt zurueck. Der Waechter sagte dort "Erst 'git pull' ausfuehren", und genau das ist die Falle: der Merge holt die entfernten Commits zurueck in die Historie, der naechste Push stellt sie auf dem Server wieder her, und zwar ohne --force. Git kann diese Lage nicht von echter ungepushter Arbeit unterscheiden. Das Skript entscheidet deshalb nicht, sondern listet die nur lokal vorhandenen Commits auf, nennt beide Moeglichkeiten samt richtigem Befehl und bricht ab. Nur der schlichte Rueckstand empfiehlt weiterhin 'git pull'. Beide Zweige gegen Wegwerf-Repos in der jeweiligen Form geprueft, nicht nur geparst - die erste Fassung stufte die Lage als "auseinandergelaufen" ein und haette dem Mac zum Pushen geraten. APPLE_DEV_BACKLOG.md nennt den einmaligen Schritt im Abschnitt "Vorher". Co-Authored-By: Claude Opus 5 --- AGENTS.md | 13 +++++++++++++ APPLE_DEV_BACKLOG.md | 15 +++++++++++++++ companion-app/scripts/ios-signieren.sh | 23 ++++++++++++++++++++++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 937446b..96fab64 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4916,6 +4916,19 @@ staleness bug this project keeps fixing elsewhere (cache-busting, OTA-bundle-ver tree is clean and `HEAD` is exactly `origin/main` (fetches first, aborts with a clear message otherwise) — added right after `cd "$APP"`, before the web build. +**Nachtrag 2026-09-07: the guard now distinguishes two cases, and the reason is a real +trap.** On that day `main`'s history was rewritten once - three commits at the tip, all of +which contained nothing but a document that has since moved to its own repository, were +removed and the branch force-pushed back to `0e84248`. **Every clone made before that date +is now *ahead* of `origin/main`, not behind it**, so `git pull` there is exactly wrong: the +merge pulls the removed commits back into the history, and the next push restores them on +the server - without even needing `--force`. Git cannot tell that apart from genuine +unpushed work, so the script does not decide: it lists the commits that exist only locally, +names both possibilities (push them, or `git fetch origin && git reset --hard origin/main`) +and aborts. Only the plain behind-case still recommends `git pull`. Both branches verified +against throwaway repositories built to each shape, not just parsed - the first version of +this fix classified the situation as "diverged" and would have told the Mac to push. + --- ## AK. Full panel↔companion-app parity audit, done in resumable chapters (started 2026-08-29) diff --git a/APPLE_DEV_BACKLOG.md b/APPLE_DEV_BACKLOG.md index 02276d9..5d0e11f 100644 --- a/APPLE_DEV_BACKLOG.md +++ b/APPLE_DEV_BACKLOG.md @@ -59,6 +59,21 @@ Nichts vorzubereiten außer einem aktuellen Stand: git pull ``` +> **Einmalig, für jeden Klon von vor dem 07.09.2026:** an diesem Tag sind drei +> Commits am Ende von `main` entfernt und der Branch per Force-Push +> zurückgesetzt worden. Ein älterer Klon steht damit **vor** `origin/main` und +> `git pull` ist dort das Falsche — es würde die entfernten Commits per Merge +> zurückholen, und der nächste Push stellte sie auf dem Server wieder her (er +> ginge sogar ohne `--force` durch). Richtig ist einmalig: +> +> ```bash +> git fetch origin && git reset --hard origin/main +> ``` +> +> Das Skript erkennt die Lage selbst, listet die betroffenen Commits auf und +> bricht ab, statt zu raten — es entscheidet aber nicht für dich, weil dieselbe +> Lage auch echte ungepushte Arbeit sein kann. + Das Skript prüft das selbst und **bricht ab**, wenn der Arbeitsbaum nicht sauber oder `HEAD` nicht gleich `origin/main` ist - sonst signierte es einen veralteten Stand. Ebenso bricht es ab, wenn das Zielgerät nicht im Team eingetragen ist diff --git a/companion-app/scripts/ios-signieren.sh b/companion-app/scripts/ios-signieren.sh index 85e41bd..631063a 100755 --- a/companion-app/scripts/ios-signieren.sh +++ b/companion-app/scripts/ios-signieren.sh @@ -61,7 +61,28 @@ LOKAL="$(git rev-parse HEAD)" FERN="$(git rev-parse origin/main)" if [ "$LOKAL" != "$FERN" ]; then echo "FEHLER: Lokaler Stand ($LOKAL) weicht von origin/main ($FERN) ab." >&2 - echo "Erst 'git pull' ausfuehren - sonst signiert dieses Skript einen veralteten Stand." >&2 + if git merge-base --is-ancestor "$LOKAL" "$FERN"; then + echo "Dieser Klon ist nur zurueck. 'git pull' holt den Rest, dann erneut versuchen." >&2 + else + # Hier liegen Commits, die origin/main nicht hat. Git kann NICHT unterscheiden, + # ob das eigene ungepushte Arbeit ist oder ob die Gegenseite sie absichtlich aus + # der Historie geworfen hat - beides sieht gleich aus. Am 07.09.2026 war es der + # zweite Fall, und dort waere ein Push (er ginge sogar ohne --force durch) die + # stille Wiederherstellung genau dessen, was entfernt werden sollte. Deshalb + # entscheidet das Skript hier nichts, sondern legt beide Moeglichkeiten vor. + echo "" >&2 + echo "Diese Commits liegen nur hier und nicht auf origin/main:" >&2 + git log --oneline "$FERN..$LOKAL" >&2 + echo "" >&2 + echo "Dafuer gibt es zwei Gruende, und sie verlangen das Gegenteil voneinander:" >&2 + echo " a) eigene, noch ungepushte Arbeit" >&2 + echo " -> git push" >&2 + echo " b) die Gegenseite hat sie absichtlich aus der Historie entfernt" >&2 + echo " -> git fetch origin && git reset --hard origin/main" >&2 + echo "" >&2 + echo "Im Fall b) waere ein Push - und ebenso ein 'git pull' mit Merge - genau die" >&2 + echo "Wiederherstellung dessen, was dort entfernt wurde. Also erst nachsehen." >&2 + fi exit 1 fi echo " HEAD == origin/main ($LOKAL), aktuell."