update.sh: erklaeren, warum ein Vorspulen scheitert

Das Skript brach mit „laesst sich nicht ohne Merge aktualisieren. Bitte von
Hand pruefen" ab — und liess den Betreiber damit allein. Genau dieser Fall
ist auf dem Server aufgetreten, nachdem hier die Historie neu geschrieben
wurde: Alte und neue Commits haben dann keinen gemeinsamen Vorfahren mehr.

Jetzt unterscheidet das Skript die beiden Ursachen und nennt den Ausweg. Bei
neu geschriebener Historie steht der vollstaendige Befehl da, samt dem
Hinweis, dass die .env davon unberuehrt bleibt. Bei eigenen Commits werden
sie aufgelistet.

Beide Zweige an nachgebauten Repositories geprueft.
This commit is contained in:
Florian Wilde
2026-08-16 01:21:16 +02:00
parent 0ec532296d
commit d0057f038c
+35 -2
View File
@@ -70,10 +70,43 @@ BRANCH="$(git rev-parse --abbrev-ref HEAD)"
info "Hole neuen Stand von origin/$BRANCH …" info "Hole neuen Stand von origin/$BRANCH …"
git fetch --quiet origin git fetch --quiet origin
# --ff-only: lieber abbrechen als eine Merge-Situation erzeugen, die auf einem # --ff-only: lieber abbrechen als eine Merge-Situation erzeugen, die auf einem
# Server niemand auflösen will. # Server niemand auflösen will.
git merge --ff-only --quiet "origin/$BRANCH" || if ! git merge --ff-only --quiet "origin/$BRANCH" 2>/dev/null; then
fail "Der lokale Stand lässt sich nicht ohne Merge aktualisieren. Bitte von Hand prüfen." echo "" >&2
echo "✗ Der lokale Stand lässt sich nicht ohne Merge aktualisieren." >&2
echo "" >&2
if git merge-base --is-ancestor HEAD "origin/$BRANCH" 2>/dev/null; then
# Kann eigentlich nicht sein — dann wäre das Vorspulen geglückt.
echo " Grund: unklar. Bitte 'git status' und 'git log --oneline -5' ansehen." >&2
elif ! git merge-base HEAD "origin/$BRANCH" >/dev/null 2>&1; then
# Kein gemeinsamer Vorfahre: Die Historie wurde neu geschrieben, etwa
# durch einen Force-Push. Der Inhalt ist derselbe, die Commits haben
# nur neue Kennungen.
cat >&2 <<'HINWEIS'
Grund: Der Verlauf auf dem Server wurde neu geschrieben (Force-Push).
Alte und neue Commits haben keinen gemeinsamen Vorfahren mehr.
Der lokale Stand lässt sich verwerfen und durch den vom Server ersetzen:
git fetch origin
git reset --hard origin/main
./update.sh --force
Das betrifft nur versionierte Dateien. Die .env und alles, was nicht im
Repository liegt, bleibt unberührt.
HINWEIS
else
echo " Grund: Hier liegen eigene Commits, die es auf dem Server nicht gibt:" >&2
git --no-pager log --oneline "origin/$BRANCH..HEAD" | sed 's/^/ /' >&2
echo "" >&2
echo " Entweder pushen — oder mit 'git reset --hard origin/$BRANCH' verwerfen." >&2
fi
echo "" >&2
exit 1
fi
AFTER="$(git rev-parse HEAD)" AFTER="$(git rev-parse HEAD)"