OXYGENHUB

Releases 1

oxy 0.4.4 v0.4.4 · ✔ signed by Andy McCall · andymccall ·

Trust and audit
  • A fresh clone takes tags made before a key rotation (issue #114). A tag's signature was checked against the current trust policy with no regard for rotation, so every tag signed by a key since rotated away from was refused, and a fresh oxy clone of a repository with such a tag failed (this repository's own v0.1.0). A tag signed by a predecessor of a key the policy names is accepted when it is dated before that key's successor was made; a superseded key makes no new ones, and revoked keys never count.

  • SLSA provenance of a receipt (oxygenhub#239). oxy receipt export --format slsa writes what a valid receipt says as an in-toto Statement with an SLSA provenance v1 predicate, in a DSSE envelope signed with your key, the runner's signed receipt riding along inside it. oxy identity export --pem writes the public key cosign and other DSSE verifiers check it with.

  • Repositories kept in a bucket answer quickly (oxygenhub#228, #234). A forge serving a repository from GCS or S3 opened a new client for every request, read large packs by range without keeping what it read, asked the bucket for a loose copy of every packed object it read, and asked again and again about objects it lacked. Clients are now shared per bucket and credentials, ranges and sizes are kept on disk, packs are looked in first, and a key found missing is taken as missing for 30 seconds unless this process writes it. On a hosted repository in GCS, negotiate went from 7-10 s to well under a second and bucket requests from about 540 a minute to about 30. The store counts its requests by kind, for a server to show.

  • A quicker log and an instant clean diff (issue #94). The workspace's state index keeps its changes newest first, and the log takes them as a list, with no map of every change and no sort. A diff whose working copy changes nothing is empty without loading the base. On VS Code at 20 000 commits, log -n 20 went from 34 ms to 30 ms and a clean diff from 48 ms to 30 ms.

  • A credential helper that does not read its input works (issue #115). An erase that exits without reading what oxy sends it failed now and then with Broken pipe; a closed pipe is no error now, as in Git.

  • gc leaves a fully packed store as it is. gc repacks at its harder compression level, and a store that was already one such pack with nothing loose was rewritten every time, the same pack again: 37 seconds for this repository's 48 000 objects on a forge, nightly, under the repository's write lock. Such a store is now left alone.

  • A switch names what it takes off disk (issue #102). oxy bookmark switch and oxy checkout printed only how many files they removed, easy to miss when a switch to a bookmark lacking 80 files took an editor's project file with them. They now name the first few removed files, with a warning when twenty or more go.

  • Binary files' current versions found without whole closures (issue #107). Which replacement of a binary file is live was decided by building each replacing change's entire closure; on a history as long as VS Code's (166,000 commits) each is a hundred thousand changes, the memo could not keep them, and oxy git verify spent its day rebuilding them. A bounded walk that keeps nothing answers the same.

  • --carry takes work the target already has (issue #100). Switching bookmarks or checking out with --carry refused when uncommitted files were byte-for-byte what the target state holds, as after a proposal of that work landed, leaving only --discard. Such work is now already applied: no conflict, nothing to carry, and the rest of the work comes along.

  • Full hashes as --json prints them (issue #103). A change named by its full 64-digit hash without the #, as oxy bookmark show --json and the hub's API print heads, resolves wherever a change is named (bookmark set, bookmark create, checkout, …), so JSON output feeds back into commands.

  • Large new files are not snapshotted unseen, and past snapshots expire (issue #98). A 1 GB image left untracked in a working tree was taken in by the next status and kept by the operation log for good: deleting the file and running gc --now freed nothing. Now a new, untracked file over snapshot.max-new-file-size (default 100 MiB) is left out and named by status, with how to ignore it or raise the limit; tracked files and files already in the working copy are unaffected. Past working-copy snapshots keep their files only for core.snapshot-retention (default 7 days), so gc prunes what only they held, and oxy gc --expire-snapshots --now does it at once. undo and op restore to an operation whose working copy has expired keep the files as they are.

  • oxy undo undoes this workspace's last command (issue #99). It undid the repository's newest operation, whichever workspace made it: in a repository with several workspaces an undo could take back another workspace's commit or merge, and it said only which operation it went back to. Operations now record their workspace, and undo takes back this workspace's last command, leaving other workspaces' work as it is. On a bookmark both share, only its own heads go; a change another workspace built on it, or the workspace it would take away, refuses the undo and names it. Undo now says which command it undid and what that changed, passes over pushes (the remote keeps what it was sent), and warns when an undone commit is already on a remote. oxy amend warns when it rewrites a change a remote already has, so the next push will need --force.

  • gc can keep what a host names (oxygenhub#126). Repo::gc_keeping keeps extra blobs and their chunks beside what history reaches, so a forge's job artifacts, referenced only from its own database, survive garbage collection.

  • oxy remote remove removes all of a remote (issue #86). It blanked the URL alone: the token, CA and store settings stayed in the config and the remote's tracking bookmarks in the view, read later as if current. Now every remote.NAME.* key goes, with its tracking bookmarks and a store remote's mirror; an unknown name is refused.

Assets