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
| Task | API and explanation |
|---|---|
| Locate, open, or initialize a repository | repository, RepositoryLocation, Repository |
| Compute or parse full object identities | object, ObjectFormat, ObjectId |
| Decode or construct snapshots and metadata | tree, commit, tag |
| Read loose and packed objects together | objects, Objects, ReadLimits |
| Write individual objects | loose, LooseObjects |
| Read or produce pack artifacts | pack |
| Walk ancestry, test reachability, find merge bases | history |
| Combine content, trees or commits and publish conflicts | merge |
| Cherry-pick, revert or rebase explicit commits in memory | replay |
| Read Git operation state and prepare explicit recovery | sequencer |
| Split, sign and verify commit and tag signatures | signing |
| Save/apply stash snapshots and edit their history explicitly | stash |
| Resolve names, conditionally update refs, inspect reflogs | refs |
| Parse, resolve, interpret, or edit configuration | config |
| Interpret named remotes and refspecs | remote |
| Read and validate submodule definitions | submodule |
| Fetch, push, or clone with explicit publication | fetch, push, clone |
| Use configured-remote convenience workflows | workflow |
| Compose everyday operations on a trusted local repository | Repo, repo |
| Use HTTP/SSH and credentials | transport, remote::CredentialStore |
| Compare snapshots and file contents | Objects::compare_trees, content_diff, rewrites |
| Parse and apply text hunks to in-memory bytes | apply |
Write unified patches as git diff does | patch, Objects::write_patch |
Read .gitattributes and diff drivers | attributes, patch::DiffAttributes |
| Print paths, modes, statuses and dates as Git does | display |
| Manage the index and working tree | index, status, checkout, ignore |
| Plan retention, repack, or coordinate mutation | retention, 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.
| Feature | Adds | Execution requirements |
|---|---|---|
http | Smart HTTP(S) transport with Rustls | Caller-owned Tokio runtime for transport APIs |
ssh | System OpenSSH transport on macOS/Linux | OpenSSH and a caller-owned Tokio runtime |
tracing | Operation spans and bounded-work counts | Caller 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 checkoutWith 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 describeprints 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 diffprints, written to anio::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 resetdoes. - retention
- Object retention planning, additive repacking, and isolated maintenance.
- revision
- Git revision expressions: parsing and resolving names like
main~2,v1.0^{tree}orHEAD:src/lib.rs, and commit ranges likemain..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
.gitmodulesbytes. - 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_treesandObjects::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. - Peel
Error - A failed read-only resolution, with the exact link being examined.
- Peel
Limits - Work limits for resolving one object through a chain of annotated tags.
- Peeled
Object - Resolved identity and kind, retaining the original tip and every intervening tag identity.
- Tree
Change - One added, removed or changed leaf path.
- Tree
Compare Limits - Input and output bounds for one recursive tree comparison.
- Tree
Value - The identity and mode recorded for a leaf path in a tree.
Enums§
- Change
Status - How one path changed, with the letter Git prints for it in
--name-statusandstatus --porcelainoutput. - Peel
Failure - Reasons a tag chain cannot be resolved. No failure changes storage.
- Shared
Permissions - Permission adjustment for newly created shared repository metadata.
- Tree
Compare Error - A structural comparison failed; no partial result is returned.
Type Aliases§
- Result
- A
std::result::Resultwhose error defaults to the crate-levelError.