Skip to content

Semantics & limitations

Plumbing — writeBlob/writeTree/writeCommit/readCommit/log/refs/ branches — is covered by the test suite and is what this whole package is built around. Worktree operations (checkout, add, status) want a real disk; if you need them, hydrate to a scratch directory (e.g. /tmp on a platform that offers one per invocation) and use node:fs there instead.

There’s no mkdir equivalent to call — mkdir is a no-op, and a directory “exists” exactly when keys live under it, the same way object storage itself works. list()’s delimiter semantics are what make readdir() possible on top of that — see the ObjectStore guide.

readlink → ENOENT, symlink → EPERM. Bare repositories don’t contain symlinks as data (they’re stored as blobs with a special mode, not real filesystem symlinks), so this is a non-issue in practice.

An empty repo and missing data are different failures

Section titled “An empty repo and missing data are different failures”

Functions that read a ref (getTreeFromRef, getCommitLog, listBranches, …) treat the ref simply not resolving — an unborn branch, a genuinely empty repository — as a normal, expected condition: they return [] (or null), not an error. That’s the only case they treat that way.

Once a ref has resolved to a real commit sha, any object underneath it that turns out to be unreadable — the commit itself, a tree, a blob a stored pack doesn’t actually contain — is a different failure: the repo’s storage is inconsistent, not empty. That’s surfaced as a thrown GitObjectNotFoundError (message: “…is missing from storage. The repository may need to be re-pushed to repair it.”), not folded into the same [] a genuinely empty repo returns.

Unknown object sizes are not “too large”

Section titled “Unknown object sizes are not “too large””

getObjectSize(repo, oid) returns a number for a packed object it can read, and null when it can’t: a loose object, an object no pack indexes, a store without getRange, or a delta prefix too short to yield its header. null means unknown, and a caller must then read the object and apply its size limit to the result — never treat null as “too large”. Reporting an unknown size as oversized would silently hide readable files, and the fallback is what keeps the limit correct on stores that can’t serve byte ranges.

Object storage has neither. A caller that needs several keys to become visible together (or an atomic move) needs its own coordination layer on top — this package doesn’t pretend otherwise.