Skip to content

gitai 0.4.2

Latest

Choose a tag to compare

@feder-cr feder-cr released this 05 Nov 19:59

A correctness and reliability release, recommended for everyone running the storage
core (shadow or authoritative mode), above all with Postgres, several nodes, or agents
that can push. It also switches the default bundled git to the v2.56.0 release.

Fixes

  • A rejected push update could be recorded in the database (authoritative, two or
    more nodes). git hands the updates of a non-atomic push that it rejected for a wrong
    old value to the reference-transaction hook. When a reference had moved away and back
    on another node, the old value matched the database but not this node's copy: the
    client was told [remote rejected] (incorrect old value provided) while the database
    kept the update, and the node's copy diverged until the reference was written again.
    The whole push is now refused in that case, as for a stale create since 0.4.1. Shadow
    mode logs and counts it, and never refuses.
  • What a refused non-atomic push leaves behind is now documented exactly. git runs a
    non-atomic push as two transactions, deletions first. A refused deletion fails the
    first and nothing lands; a refused create or update fails the second, after the
    deletions git accepted have landed. The client gets
    fatal: in 'prepared' phase, update aborted by the reference-transaction hook (SSH)
    or a hang-up (smart HTTP), with no status per reference (LIMITATIONS).
  • Postgres connection churn failed writes under load. The store used database/sql's
    defaults (unbounded open connections, 2 idle), so a busy node opened about two new
    connections per changeset; with 200 concurrent writers 919 of 2000 changes failed with
    connection resets. The pool is now bounded and reused: 0 failures in the same runs.
    This is a reliability fix; on a single busy repository the speed gain is small
    (2-11% lands/min).
  • Reference names git can't hold side by side (a directory/file pair such as
    refs/heads/a and refs/heads/a/b). A create that conflicts with an existing name is
    refused alone by the update hook, with the reason on the client's terminal; the
    database checks again at commit; a node's catch-up no longer stops on a legal history
    in which one name of a pair was deleted before the other was created.
  • Agents could reach reserved or decoy references through a symbolic branch.
    Symbolic branches are now judged by their written target on RPC write paths,
    first_parent_ref and the start point are read exactly, and agents cannot create or
    update references under the decoy namespaces.

New

  • graft storage delete-conflicting-ref REF EXPECTED_TARGET (RPC
    DeleteConflictingReference, authoritative mode only) repairs a repository that
    already holds such a pair: it deletes one side, only if it still has the expected
    value, as an ordinary changeset that every node applies.
  • Postgres pool settings under [graft.storage]: database_max_open_conns (32),
    database_max_idle_conns (same as max open), database_conn_max_idle_time (5m),
    database_conn_max_lifetime (30m). Keep the sum over all nodes below the server's
    max_connections, with room for a graceful upgrade, when a node briefly runs two
    pools. Setting them with SQLite is a startup error. See CONFIGURATION.
  • Metric graft_storage_prepared_step_seconds{kind,step} splits the time under the
    repository's write lock into record, local read, pack, commit and durability.
  • Conformance harness: stock git against gitai in every storage mode, now a CI step.
  • Design: DB-first writes (doc/graft/design/dbfirst-writes.md, with a TLA+ model).
    A plan to lift the per-repository write bound for server-side writes; nothing of it
    is enabled in this release.

Changes

  • Default bundled git is the v2.56.0 release (was 2.55.0-rc1). The test suites pass
    with it; in the land-path benchmark the median p99 changed by +7.4% (within run-to-run
    noise), throughput unchanged (BENCH).

Upgrade

No data migration. With Postgres, check the new pool limits against your server's
max_connections (defaults: 32 per node). The 0.4.1 advice on references over 1024
bytes still applies.