Skip to main content

Crate girt

Crate girt 

Source
Expand description

Git objects, repositories, and explicit workflows for Rust applications.

girt is a Git library for applications that need to read and write Git data directly. Use it to inspect a repository, construct snapshots, traverse history, or publish references. The application chooses when each effect happens: storing a commit does not move a branch, and moving a branch does not update a working tree. The API is experimental.

§Design principles

Git’s on-disk formats and semantics define the supported behavior. girt preserves accepted object bytes and their identities, including non-UTF-8 names and messages. Unsupported cases are refused explicitly rather than silently approximated. Support is specific to each operation; opening a repository does not establish that every Git feature used by that repository is supported.

The library models Git concepts directly. A repository locates storage and selects its hash format; objects describe immutable content; references give that content mutable names. Configuration, resource limits, cancellation, and publication policy are explicit where the operation needs them. No application-wide runtime or tracing subscriber is installed.

Use Repo for trusted local use with Git-default discovery, lazy loading, and default limits. Use Repository for explicit control over configuration, limits, cancellation, and untrusted input. Repo::repository exposes the underlying repository when an operation needs that control; repo describes the convenience layer’s policies and limitations.

§Quick start

Add girt to a Rust project with cargo add girt. The minimum Rust version is 1.97.1. This example also uses tempfile (cargo add tempfile) to create a disposable repository:

use girt::{InitKind, ObjectFormat, ObjectKind, PackLimits, ReadLimits, Repository};

let directory = tempfile::tempdir()?;
let repository = Repository::init(
    ObjectFormat::Sha1,
    directory.path().join("project"),
    InitKind::Worktree,
)?;

let id = repository.loose_objects().write_blob(b"hello Git\n")?;
let objects = repository.objects_with(PackLimits::default())?;
let blob = objects
    .read_with(id, ReadLimits::default())?
    .ok_or("blob missing")?;

assert_eq!(blob.kind(), ObjectKind::Blob);
assert_eq!(blob.data(), b"hello Git\n");

The repository is removed when directory is dropped. No commit or branch is created: a blob is only bytes. For an existing repository use Repository::open; to find one above a directory use Repository::discover. See repository for the distinction between selecting a location, opening its metadata, and reading its storage.

§The Git mental model

An ObjectId identifies a kind and exact payload using Git’s header and hash. It carries its SHA-1 or SHA-256 format, but proves neither existence nor object kind. A blob contains file bytes; a Tree maps byte names and modes to IDs; a Commit names a tree and ordered parents; a Tag adds metadata to another object. Objects contain IDs rather than owned child objects, so reading a commit does not recursively read its tree or parents.

Objects::read verifies storage framing and identity. Parsing the returned bytes decodes an object’s structure; validation may impose further rules. These stages remain separate so inspection tools can preserve and diagnose unusual Git data without rewriting it. Follow tree and commit for exact parsing and construction guarantees.

A reference can contain an ID or another reference’s name. HEAD commonly points to a branch; an unborn branch has a name but no ID yet. refs::References::resolve follows symbolic names; Objects::peel follows annotated tag objects. These are different operations.

§Where to go next

TaskAPI and explanation
Locate, open, or initialize a repositoryrepository, RepositoryLocation, Repository
Compute or parse full object identitiesobject, ObjectFormat, ObjectId
Decode or construct snapshots and metadatatree, commit, tag
Read loose and packed objects togetherobjects, Objects, ReadLimits
Write individual objectsloose, LooseObjects
Read or produce pack artifactspack
Walk ancestry, test reachability, find merge baseshistory
Combine content, trees or commits and publish conflictsmerge
Cherry-pick, revert or rebase explicit commits in memoryreplay
Read Git operation state and prepare explicit recoverysequencer
Split, sign and verify commit and tag signaturessigning
Save/apply stash snapshots and edit their history explicitlystash
Resolve names, conditionally update refs, inspect reflogsrefs
Parse, resolve, interpret, or edit configurationconfig
Interpret named remotes and refspecsremote
Read and validate submodule definitionssubmodule
Fetch, push, or clone with explicit publicationfetch, push, clone
Use configured-remote convenience workflowsworkflow
Compose everyday operations on a trusted local repositoryRepo, repo
Use HTTP/SSH and credentialstransport, remote::CredentialStore
Compare snapshots and file contentsObjects::compare_trees, content_diff, rewrites
Parse and apply text hunks to in-memory bytesapply
Write unified patches as git diff doespatch, Objects::write_patch
Read .gitattributes and diff driversattributes, patch::DiffAttributes
Print paths, modes, statuses and dates as Git doesdisplay
Manage the index and working treeindex, status, checkout, ignore
Plan retention, repack, or coordinate mutationretention, locks

The runnable examples compose these APIs. The compatibility record describes verified scope. Each API’s errors and limitations remain the contract for that operation.

§Features and execution

There are no default features. Repository metadata, object codecs, local storage, references, configuration, history, and native local transfer work without optional features.

FeatureAddsExecution requirements
httpSmart HTTP(S) transport with RustlsCaller-owned Tokio runtime for transport APIs
sshSystem OpenSSH transport on macOS/LinuxOpenSSH and a caller-owned Tokio runtime
tracingOperation spans and bounded-work countsCaller installs and configures a subscriber

Enable features with, for example, cargo add girt --features http. workflow owns synchronous runtime and credential orchestration for its configured-remote convenience operations. Lower-level HTTP/SSH adapters download data for explicit synchronous validation. Local filesystem operations are synchronous; applications choose their scheduling and blocking boundaries.

Run these workflows from a source checkout; check each example’s arguments and filesystem effects before using existing data:

cargo run --example loose_blob
cargo run --example compare_trees
cargo run --example content_diff
cargo run --example index
cargo run --example status
cargo run --example checkout

With tracing, DEBUG spans describe operations and phases; TRACE makes individual object reads and writes visible. Run cargo run --features tracing --example tracing for a scoped subscriber. HTTP/SSH download spans remain alive through synchronous validation or drop, including time queued for a worker. Spans record categorical outcomes and bounded-work counts; returned errors and reports remain authoritative for recovery. See the tracing guide for coverage and overhead.

§Limits, failures, and safety

Choose PackLimits when opening a reader and ReadLimits for individual objects. History adds HistoryLimits for graph work. Defaults bound untrusted input; a limit failure means the requested work exceeded the selected budget, not necessarily that the repository is corrupt. Increase only the relevant budget after considering the input’s trust and available resources. trusted() limits remove practical protections and are a caller policy decision.

Missing objects are distinct from malformed storage. Object reads return Ok(None) for absence; I/O, corruption, unsupported representations, and exceeded limits return errors. Preserve error source chains when reporting failures. Each operation returns its module’s typed error; every one converts into the crate-level Error, so application code can return Result and use ? across modules, then downcast to recover the typed error. Reference transactions can have partial effects: inspect reported outcomes before retrying. Writing storage requires the filesystem assumptions documented on the owning operation; a pathname alone is not a trust boundary.

Working-tree operations have narrower platform, byte-path, filter, and mutation contracts than object storage. Consult checkout and status before applying Git data to a filesystem.

Re-exports§

pub use commit::Commit;
pub use commit::CommitError;
pub use commit::CommitFields;
pub use commit::CommitHeader;
pub use commit::CommitHeaderRef;
pub use commit::CommitPayload;
pub use commit::IdentityDate;
pub use commit::IdentityRef;
pub use commit::Signature;
pub use config::Config;
pub use config::ConfigError;
pub use history::AheadBehind;
pub use history::HistoryError;
pub use history::HistoryLimits;
pub use history::PathHistoryError;
pub use history::Simplification;
pub use history::SimplifyError;
pub use loose::LooseObjects;
pub use object::ObjectFormat;
pub use object::ObjectFormatError;
pub use object::ObjectId;
pub use object::ObjectIdPrefix;
pub use object::ObjectKind;
pub use object::ParseObjectIdError;
pub use object::ParseObjectIdPrefixError;
pub use object::encode_blob;
pub use objects::AlternateLimits;
pub use objects::IndexedPack;
pub use objects::ListLimits;
pub use objects::LooseIds;
pub use objects::LooseObject;
pub use objects::Object;
pub use objects::ObjectHeader;
pub use objects::ObjectReadError;
pub use objects::ObjectStore;
pub use objects::Objects;
pub use objects::PackIds;
pub use objects::PackLimits;
pub use objects::ReadBlobError;
pub use objects::ReadCommitError;
pub use objects::ReadLimits;
pub use objects::ReadTagError;
pub use objects::ReadTreeError;
pub use objects::ResolvePrefixError;
pub use pack::DeltaOptions;
pub use pack::DeltaStats;
pub use pack::PackCompression;
pub use pack::PackObject;
pub use pack::PackWriteError;
pub use pack::PackWriteLimits;
pub use pack::PackWritten;
pub use pack::write_pack;
pub use pack::write_pack_with_compression;
pub use repo::Repo;
pub use repository::ColocationEdit;
pub use repository::ColocationError;
pub use repository::CreateWorktreeError;
pub use repository::InitError;
pub use repository::InitKind;
pub use repository::InitOptions;
pub use repository::OpenError;
pub use repository::OperationCleanupError;
pub use repository::OperationError;
pub use repository::OperationLimits;
pub use repository::OperationState;
pub use repository::OrphanWorktreeOptions;
pub use repository::ReflogPolicyError;
pub use repository::Repository;
pub use repository::RepositoryLocation;
pub use repository::RepositoryMetadata;
pub use repository::ShallowError;
pub use repository::ShallowRoots;
pub use repository::Worktree;
pub use repository::WorktreeAdminError;
pub use repository::WorktreeDurability;
pub use repository::WorktreeError;
pub use repository::WorktreeLinkStyle;
pub use repository::WorktreeRepair;
pub use repository::WorktreeRetirement;
pub use repository::WorktreeState;
pub use tag::Tag;
pub use tag::TagError;
pub use tag::TagFields;
pub use tree::EntryMode;
pub use tree::Tree;
pub use tree::TreeEntry;
pub use tree::TreeError;

Modules§

apply
Parse unified patches and apply their text hunks to byte content without filesystem access.
attributes
Git attributes (.gitattributes) over repository-relative byte paths.
bitmap
Reachable object sets, optional bitmap acceleration and pack/MIDX reverse indexes.
blame
Line origins across commit history, including inferred file renames.
checkout
Conservative tree checkout with literal blob bytes and native POSIX modes.
clone
Clone into a new bare repository or an ordinary repository without checkout.
commit
Commit snapshots, ordered parent edges, identities, and messages.
commit_graph
Indexed commit metadata from Git’s auxiliary commit-graph files.
config
Byte-oriented Git configuration parsing and explicit layered resolution.
content_diff
Byte-preserving line edits and explicit binary classification.
describe
Names for commits relative to the nearest tag, as git describe prints them.
display
Git’s human-readable renderings of paths and dates.
fetch
Download objects from another repository and publish remote-tracking references.
filter
Content conversion between the repository and the working tree.
history
Bounded ancestry queries over commit-graph metadata or verified commit objects.
ignore
Git ignore rules over repository-relative byte paths.
index
SHA-1/SHA-256 Git index v2/v3/v4 entries and synchronous per-worktree storage.
locks
Caller-controlled release of this process’s transient girt lock files.
loose
Read and publish individual compressed Git objects.
mailmap
Canonical names and email addresses for presenting commit identities.
merge
Three-way merging of byte content and tree entries without a working tree.
message
Commit message text: cleanup before committing, and trailers.
multi_pack_index
Object lookup across multiple packs using Git’s optional multi-pack index.
notes
Metadata attached to objects without changing their identities.
object
Object identities, hash formats, and canonical Git framing.
objects
Verified reads across loose objects, indexed packs, and alternate stores.
pack
SHA-1/SHA-256 pack v2/v3 and index v1/v2 reading and caller-owned artifact writing.
patch
Unified patches in the form git diff prints, written to an io::Write.
pathspec
Pathspecs: the patterns Git commands use to choose paths.
push
Send objects to another repository and conditionally update its references.
refs
Git references, conditional transactions and reflogs across files and reftable storage.
remote
Remote configuration, refspecs, URLs and credentials.
replay
Replay one commit onto an explicit destination, without changing repository state.
repo
Convenience operations for trusted local repositories and configuration.
repository
Repository discovery, explicit opening, and creation.
reset
Moving the current branch and resetting index entries, as git reset does.
retention
Object retention planning, additive repacking, and isolated maintenance.
revision
Git revision expressions: parsing and resolving names like main~2, v1.0^{tree} or HEAD:src/lib.rs, and commit ranges like main..topic.
rewrites
Inferred file renames and copies between Git trees.
sequencer
Git sequencer state and explicit recovery plans.
signing
Signed commit and tag payloads.
stash
Save index and working-tree snapshots without moving HEAD.
status
Read-only staged changes and configured or raw working-tree observations.
submodule
Submodule definitions from caller-selected .gitmodules bytes.
tag
Annotated tag objects and declared target kinds.
transport
Transports, protocol versions, resource limits, and cancellation and deadlines.
tree
Directory snapshots as byte names, entry modes, and object identities.
tree_diff
Tree changes combined with inferred renames and copies. This composes Objects::compare_trees and Objects::detect_rewrites_or_exact, retaining unconsumed changes and sorting by destination path. Rename inference uses stored bytes and no attributes.
workflow
Clone repositories, fetch from, push to and query configured remotes.

Structs§

Error
Any girt failure, for applications that propagate errors with ? across modules.
PeelError
A failed read-only resolution, with the exact link being examined.
PeelLimits
Work limits for resolving one object through a chain of annotated tags.
PeeledObject
Resolved identity and kind, retaining the original tip and every intervening tag identity.
TreeChange
One added, removed or changed leaf path.
TreeCompareLimits
Input and output bounds for one recursive tree comparison.
TreeValue
The identity and mode recorded for a leaf path in a tree.

Enums§

ChangeStatus
How one path changed, with the letter Git prints for it in --name-status and status --porcelain output.
PeelFailure
Reasons a tag chain cannot be resolved. No failure changes storage.
SharedPermissions
Permission adjustment for newly created shared repository metadata.
TreeCompareError
A structural comparison failed; no partial result is returned.

Type Aliases§

Result
A std::result::Result whose error defaults to the crate-level Error.