Skip to content

Design principles

These principles explain the API’s shape: why the caller passes limits, why writing an object doesn’t move a branch, and why unsupported input fails instead of falling back.

girt’s types are Git’s concepts: ObjectId, Tree, Commit, Tag, references, the index and Repository. The API follows these concepts and what its callers need, rather than the shape of the git command line, libgit2 or gix. A Git user can predict what an operation does from Git’s documentation.

For every supported feature, girt reads and writes the same bytes Git does, and its tests check this against the git executable. That includes round trips of malformed and unusual input where Git accepts it. Compressed bytes may differ from Git’s output, but identities and decoded content always agree.

When girt meets something it doesn’t support, it returns an error that names it: a repository extension, an index feature, a protocol capability, a path it can’t represent. It doesn’t fall back to something close: a refusal is a limitation the caller can see, while a silent approximation could corrupt data.

In the core API, each step that changes a repository is a separate call. Writing an object doesn’t make it reachable. Receiving a pack installs objects without moving any reference. Updating a reference doesn’t touch the working tree. The caller decides when each effect happens and which preconditions it checks first, using conditional reference updates.

The workflow module is a convenience layer for configured remotes. Its fetch installs objects and then updates remote-tracking references and tags in one call, as git fetch does. Its documentation says which references it may change and what a partial failure leaves behind.

Operations that read untrusted or unbounded data take explicit budgets: object size, delta depth, history length, pack count, reference count. Input over the selected budget is refused with an error. Budgets apply to one operation’s inputs. They don’t cap total process memory, concurrent operations or elapsed time, which remain the application’s responsibility. The defaults suit ordinary repositories. Raising them means accepting more work from a repository you trust.

Operations that delete or rewrite stored data publish and verify the replacement before they retire the original. The safety model describes the rules.

girt adds a feature when a real caller needs it, starting with jj, and ships it complete enough to use. It doesn’t add abstractions or options ahead of a caller.