diff --git a/update.sh b/update.sh index 2e32282..4e8f682 100755 --- a/update.sh +++ b/update.sh @@ -70,10 +70,43 @@ BRANCH="$(git rev-parse --abbrev-ref HEAD)" info "Hole neuen Stand von origin/$BRANCH …" git fetch --quiet origin + # --ff-only: lieber abbrechen als eine Merge-Situation erzeugen, die auf einem # Server niemand auflösen will. -git merge --ff-only --quiet "origin/$BRANCH" || - fail "Der lokale Stand lässt sich nicht ohne Merge aktualisieren. Bitte von Hand prüfen." +if ! git merge --ff-only --quiet "origin/$BRANCH" 2>/dev/null; then + 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)"