• v5.0.1 9a2d7d34f5

    v5.0.1
    CI / verify (push) Successful in 51s
    Release / release (push) Successful in 40s
    Stable

    torben released this 2026-09-12 15:37:52 +00:00 | 5 commits to main since this release

    5.0.1 - 2026-09-12 - publish: ungeborene main ist kein detached HEAD, erster Push zu leerem Remote (schliesst #96, #97)

    Author: Torben Nehmer

    • publish: ungeborene main ist kein detached HEAD, erster Push zu leerem Remote (schliesst #96, #97)

    Zwei Defekte, die zusammen dazu führten, dass eine frisch aufgesetzte Instanz
    sich über keinen dokumentierten Weg initial veröffentlichen ließ. Beide sitzen
    in publish und wurden erst beim Einrichten einer 5.0.0-Instanz aus dem
    Release-Tarball sichtbar - der Pfad, den instructions/setup-instance.md
    Schritt 14 als den ersten schreibenden Aufruf einer neuen Instanz nennt.

    Ein ungeborener Branch ist kein detached HEAD. current_branch() fragte
    git rev-parse --abbrev-ref HEAD. Nach git init -b main, vor dem ersten
    Commit, zeigt HEAD auf einen Ref, der sich nicht auflöst: rev-parse endet
    mit Exit 128 und war damit von einem echten detached HEAD nicht zu
    unterscheiden. Der erste publish einer neuen Instanz brach deshalb mit
    "Refusing to push main from a detached HEAD" ab, und Invariante 5 schneidet
    den naheliegenden Ausweg (git commit von Hand) ab. Die Funktion liest jetzt
    git symbolic-ref --short -q HEAD - was HEAD benennt statt worauf es
    zeigt. Damit beantwortet die Branch-Prüfung den ungeborenen Fall korrekt,
    statt für ihn ausgesetzt werden zu müssen: sie vergleicht main mit main
    und lässt durch. Ein echter detached HEAD wird unverändert abgelehnt, und ein
    --branch, das nicht dem ausgecheckten entspricht, ebenfalls.

    Ein nie gepushter Branch ist nicht "nicht ahead". _local_ahead_of_remote()
    entscheidet, ob ein sauberer Working-Tree trotzdem etwas zu pushen hat, und
    gab False zurück, sobald kein Tracking-Ref existierte. Genau das ist der Fall
    bei einem frisch angelegten, leeren Remote-Repository: der lokale Commit stand,
    publish meldete "Nothing to commit" und pushte nie - beliebig oft
    wiederholbar. Unterschieden wird jetzt über git ls-remote --exit-code, dessen
    Exit-Code die drei Lagen ohne Textvergleich trennt (0 = Ref vorhanden,
    2 = Remote erreichbar und ohne diesen Ref, 128 = unerreichbar oder gar nicht
    konfiguriert); auf die Meldung zu matchen schiede aus, weil git sie übersetzt.
    Nur der mittlere Fall gilt als "ahead", und auch dort nur, wenn lokal
    überhaupt ein Commit existiert. Ein unerreichbares Remote behält bewusst das
    bisherige Verhalten, damit Offline- und Nur-lokal-Instanzen keine
    Verhaltensänderung sehen. remote_ref_exists() bleibt unangetastet - sein
    zweiter Aufrufer reconcile() meint damit weiterhin richtig "nichts zum
    Abgleichen da".

    tools/CONTRACT.md zieht beides nach: die publish-Zeile beschrieb den
    Strandungsfall bisher als gelöst, was für einen nie gepushten Branch nicht
    stimmte, und der Fehlerkontrakt benennt die Branch-Prüfung jetzt als
    eigenständigen Exit-1-Grund. instructions/setup-instance.md und INSTALL.md
    blieben inhaltlich richtig - sie hatten den Umweg nie beschrieben, sondern den
    Weg, der jetzt tatsächlich funktioniert.


    This note is a snapshot of the CHANGES.md entry as it stood when the tag was cut, and
    is never edited afterwards. The maintained version of this text - including any later
    correction - is the entry for this version in CHANGES.md in the repository.

    Downloads