Skip to content

v0.19.0

Latest

Choose a tag to compare

@github-actions github-actions released this 30 Oct 11:36
0d8d537

0.19.0 (2026-10-30)

⚠ BREAKING CHANGES

  • api: a diff-commit patch that does not apply now gets 409 conflict instead of 422 invalid, and a diff payload that is not a valid patch or that names an invalid path now gets 400 invalid instead of 422.
  • api: GET .../files without recursive lists every file in the tree instead of the direct children. It answers 422 when that listing passes the 64 MiB git output budget. Send recursive=false to get the direct children.
  • api: when another writer moves the branch after the server wrote the commit, commit-pack and diff-commit now answer 409 with result.status failed instead of conflict, and the body carries the written commit in commit and result.new_sha.
  • api: GitHub sync creates during a rolling upgrade. Only an upgraded worker adopts the GitHub default branch for a sync create that omits default_branch. A sync that an older worker runs leaves the repo on main until the next sync by an upgraded worker. An older replica's PATCH /repo to main before that sync does not stop the adoption, so the repo still moves to the GitHub branch. Upgrade every replica before you send GitHub sync creates that omit default_branch, or send default_branch explicitly. Tracked in #609.
  • api: a commit-pack or diff-commit request that changes nothing now gets 412 precondition_failed "no changes to commit" instead of an empty commit. A commit-pack or diff-commit stream that ends before its eof chunk now gets 412 instead of 400.
  • api: GET /api/v1/repos/files/metadata and GET /api/repos/{repo_name}/files/metadata now send only the subject line of each commit message in the commits map (the first paragraph as one line, the same as git's %s). Clients that need the body or the trailers must read GET /api/v1/repos/commit.
  • api: GET /api/v1/repos/commits and GET /api/repos/{repo_name}/commits now send only the subject line of each commit message (the first paragraph as one line, the same as git's %s). Clients that need the body or the trailers must read GET /api/v1/repos/commit.
  • api: files and files/metadata calls without limit and cursor return every entry instead of one page, and files/metadata answers 429 when the files under path have more than 50,000 distinct last commits.
  • api: a failed merge guard on POST /api/v1/repos/merge and POST /api/repos/{repo_name}/merge now answers code ref_guard_failed instead of conflict, with guard and current_sha members. A merge with expected_source_sha whose source branch does not exist answers 409 ref_guard_failed with current_sha 40 zeros instead of 404. Clients that branch on code conflict for a merge guard must check ref_guard_failed.
  • api: a stale expected_target_sha on POST /api/v1/repos/merge and POST /api/repos/{repo_name}/merge now answers 409 with a problem body, code conflict, instead of 412 with result.status precondition_failed. Raw HTTP callers that check for 412 must check for 409 and the conflict code. SDK callers keep the same error type.
  • api: POST /repos now answers 200 with the existing repo instead of 409 for a plain, copy or fork create of a name that a finished repo without an upstream holds. A repeat copy or fork answers before it reads its source.
  • api: POST /repos now answers 503 with Retry-After instead of 409 for a plain, copy or fork create of a name whose fork or copy create has not finished, including one that crashed or whose last step failed. A sync create pending after its upstream link was removed gets the same answer. DELETE /repos/delete clears such a name.
  • s3wal: S3WAL only, PostgreSQL and SQLite are not affected. An S3WAL bucket written by v0.16.0 through v0.18.0 must be converted before this release serves it. Stop serve and wait for it to exit, take a backup, replace the binary, run openstorage s3wal-meta convert --to 2, then start serve. Upgrade an older bucket to v0.18.0 first. To go back, stop serve, take a backup, and run openstorage s3wal-meta convert --to 1 with this release before starting the older release. See docs/how-to/deploy-production.md#upgrading-the-s3wal-metadata-format.
  • api: POST /repos with upstream or a base_repo sync, for a name that a repo with the same upstream and the same forward_pushes holds, now answers 200 with the existing repo instead of 409. A repeat create of a pending sync repo by a token with only repo:write now answers 403 instead of 409.

Features

  • api: a fork or copy is pending until its ref write (#450) (49bc1ac)
  • api: a repeat create of a finished repo answers 200 (#453) (295de82)
  • api: a repeat sync create of the same upstream answers 200 (#438) (0a4994f)
  • api: answer a stale merge expected_target_sha with 409 conflict (#536) (198cc45)
  • api: answer failed merge guards with 409 ref_guard_failed (#571) (d7c1eb8)
  • api: honor expected_source_sha on merge (#535) (0341af9)
  • api: name invalid fields from the single-field body validators (#443) (e1beeeb)
  • api: name the invalid field in invalid_params on body decode failures (#436) (66f5c32)
  • api: send a Deprecation header on the deprecated pull-upstream and base routes (#460) (ea43a01)
  • api: send only the subject line in commit list entries (#575) (f0c975a)
  • api: send only the subject line in files/metadata commits (#579) (5e9bbe6)
  • meta: add the ADR-50 schedule transitions for S3WAL metadata v2 (#448) (27b24bd)
  • meta: add the S3WAL metadata v1/v2 conversion (ADR-51) (#441) (ba8365a)
  • meta: complete the S3WAL local schedule (#449) (ae6e3a0)
  • s3wal: repair or refuse unfinished creates on convert --to 1 (#489) (5b06087)
  • s3wal: run S3WAL upstream syncs on the durable local schedule (#451) (f0153d4)
  • s3wal: schedule upstream syncs from S3WAL git-surface pushes (#454) (f5d362a)
  • s3wal: serve reads metadata format v2; add s3wal-meta convert (#444) (116175f)
  • s3wal: store create state in metadata v2; release-pair harness covers conversion and downgrade (#446) (cb885a7)

Bug Fixes

  • api: add ref_guard_failed problem members to the notes 409s (#573) (0e6133b)
  • api: answer "repository already detached" on DELETE .../upstream without an upstream (#468) (6005169)
  • api: answer 409 conflict when a diff-commit patch does not apply (#611) (77424c8)
  • api: answer 412 no changes to commit on commit writes that change nothing (#605) (54f9bca)
  • api: answer 413 when a commit-pack passes 262144000 decoded bytes (#610) (e491cf4)
  • api: answer a lost commit CAS with 409 failed and the written commit (#606) (9cec7ea)
  • api: answer the pack-reservation 429 with status unavailable (#600) (dc40992)
  • api: list files recursively when the call sends no recursive (#602) (8cb2588)
  • api: page recursive files listings without listing the whole tree (#614) (5620494)
  • api: read path params and tree paths literally in git pathspecs (#578) (0a39336)
  • api: return every entry from file listings without limit or cursor (#572) (3ff6012)
  • api: take the GitHub default branch when a sync create omits default_branch (#607) (f6d96da)
  • compose: give serve 30 s to drain and tear down on docker stop (#493) (a09d656)
  • deploy: stop the AWS systemd unit with KillMode=mixed (#479) (a4be26e)
  • deps: bump Go toolchain to 1.27.3 for GO-2026-6809 (#546) (f58a6f0)
  • deps: bump gocloud.dev to v0.47.0 for the fileblob root-key fix (#510) (0274c7e)
  • deps: bump golang.org/x/net to v0.62.0 (GO-2026-6860, GO-2026-6866) (#622) (7a11b9c)
  • githttp: report stale ref locks and document their manual removal (#485) (dda15af)
  • gitread: frame git log fields with NUL bytes (#582) (6458ece)
  • gitread: read commit dates that git cannot parse (#584) (fca3943)
  • gitread: read grep paths that hold a newline (#585) (e42338e)
  • gitread: return blame original_path unquoted (#591) (d283ba4)
  • image: bump the alpine runtime base to 3.24.3 (#551) (302960e)
  • jobs: bound River.Close when no drain stopped the jobs (#642) (23b715e)
  • jobs: give River jobs a 2-hour deadline instead of River's 1-minute default (#637) (47cc9bc)
  • jobs: rescue crashed sync and push jobs once their claim lease expires (#644) (c82e7dc)
  • s3wal: complete the --force help and share the op-log scope names (#500) (f69d4f6)
  • s3wal: give the meta.json quarantine one clear error and document it at the hook (#528) (e182cba)
  • s3wal: keep serve running when meta.json goes back to an older seq (#496) (287cda6)
  • s3wal: latch the rollback refusal when a cached meta.json stops decoding (#514) (5cbaba6)
  • s3wal: quarantine meta.json until restart when an edit is found after adoption (#523) (d45ad2a)
  • s3wal: refuse a hook ref update on a corrupt meta.json (#476) (aab68a4)
  • s3wal: refuse a hook ref update on a metadata format mismatch (#465) (c3f6d8c)
  • s3wal: reject every row content the background loops rely on at meta.json decode (#518) (3fb638d)
  • s3wal: reject impossible id counters in meta.json instead of panicking (#486) (48076b6)
  • s3wal: route every meta.json latch through one refusal choke point (#522) (c49b99b)
  • s3wal: tag org-key refresh round trips in the S3 op log (#498) (8ae1314)
  • s3wal: turn meta.json lane-shape and counter panics into corrupt-document errors (#509) (2c70de2)
  • serve: stop git children when the shutdown drain times out (#472) (66fedf1)
  • serve: stop REST and hydration git children on drain timeout (#483) (84394f6)

Performance Improvements

  • gitread: diff only what can change a files/metadata answer (#586) (38fb0be)
  • gitread: send last-commit diffs ahead within a window (#589) (e5d34fd)
  • s3wal: reuse the decoded meta.json on a 304 for read-only callers (#495) (1a1a201)