OXYGENHUB

Releases 1

oxy 0.7.0 v0.7.0 · ✔ signed by Andy McCall · andymccall ·

Trust and audit
  • Many objects are read in pack order (issue #137): Store::get_many (a clone's checkpoint, a fetch's objects) reads packed objects by pack and offset, each thread a run of them, so a spinning disk sweeps instead of seeking across the packs; results keep the asked order. The server's gathering of a VS Code-sized checkpoint (tens of thousands of objects in ~95 packs) was the slow part of a depth-0 clone on Earth.
  • Windows paths print plainly (issue #143): a repository's root showed as \\?\C:\work\demo in every message, Windows' verbatim form from canonicalize; oxy now drops the prefix where the plain path says the same (oxy_core::portable::canonical). Found running the shipped Windows build on a Windows 11 VM.
  • Oxygen's CI writes a test report beside its coverage (issue #139): the test job runs under cargo-nextest (.config/nextest.toml, profile ci) as well as cargo-llvm-cov, keeping a JUnit report whether or not the tests pass, for the hub's Tests tab.
  • Pushing a new bookmark sends only what the remote lacks (issue #142). A push was worked out against the remote's heads for that bookmark alone, so a bookmark new to the remote sent its whole history again: slow on a big repository, and OxygenHub's push protection scanned all of it (and refused a proposal's bookmark for an example key in a change main had had for weeks). The heads of every bookmark the remote lists now count as already there.
  • A binary file's or subrepo pin's conflict can be settled from the command line (issue #140). Two changes that replaced the same binary file, or moved the same subrepo pin, leave a replace conflict with no markers to edit, and every commit was refused until it was settled, which only a hosted edit could do. oxy resolve PATH… now settles it with what the working copy holds at the path (the file, or the subrepo's pin): the next commit is a resolution replacing every version with it. A path with no replace conflict is refused, and a choice is forgotten once committed.
  • The object store works where hard links are refused (issue #141). Android forbids apps hard links in their own storage, so the OxygenHub app's phone runner could clone nothing (Permission denied). Where a link is refused, objects are renamed into place with renameat2(RENAME_NOREPLACE): as atomic, and still never over a name that is taken.
  • Rendering a big tree is many times faster, and clone, pull, switch and oxy workspace add stop rendering it twice (issue #137). Measured on the VS Code history's depth-0 clone (19,545 files, 166,425 changes), oxy workspace add took 467 s on Earth and 176 s on an 8-core workstation, 11 GB at its peak; it now takes 7.5 s and 1.8 GB on the workstation. Three causes: (1) whether one change depends on another, which rendering asks about every deleted line, was answered by a depth-first walk that compared a change with the one sought only on coming back up to it, so it went through thousands of changes first although the answer is nearly always a direct dependency (spec §8.1): 262,678 questions took 4.4 billion steps and 838 CPU-seconds, and now take 5 CPU-seconds, with the same answers; (2) finding the subrepos rendered every file of the tree, after every clone, pull, switch and workspace add, where reading the tree and the subrepos' pins is enough; (3) a new workspace started on the target state with an empty directory, so the checkout's first snapshot found the whole tree deleted and rendered it to say so. OXY_TIMINGS=1 now also says how a checkout's files were ordered (graph: single order…) and how its blobs were read.
  • oxy serve takes a push of more than 2 MB (issue #138). It set no request limit of its own, so axum's default of 2 MB applied, and a larger push part was cut off with Broken pipe at the client and nothing in the server's log. It now takes up to 4 GiB a request (oxy_server::BODY_LIMIT), OxygenHub's default push_body_limit; OxygenHub was not affected.
  • A push no longer sends a replaced or removed binary file's old content again (issue #136). A bundle carried both the old and the new blob of every binary file a change replaces, so a change removing ~1,100 tracked cache files (oxygenhub-android's set-up) pushed all of them again, over 100 MB, though the hub stored each when it was added. The old blob is always the new blob of a change the replacement depends on, which the receiver already holds or which the same bundle carries, so pushes and fetch answers now carry only the new one.

Assets