1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
//! 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:
//!
//! ```rust
//! 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");
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! 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](https://github.com/joshka/girt/tree/main/examples) compose these APIs.
//! The [compatibility record](https://github.com/joshka/girt/blob/main/docs/compatibility.md) 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:
//!
//! ```sh
//! 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](https://github.com/joshka/girt/blob/main/docs/tracing.md) 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.
// Let library unit tests share the Git-generated integration fixtures.
extern crate self as girt;
pub use SharedPermissions;
pub use ;
pub use ;
pub use ;
pub use ;
pub use LooseObjects;
pub use ;
pub use ;
pub use UnverifiedObject;
pub use ;
pub use ;
pub use ;
pub use Repo;
pub use ;
pub use ;
pub use ;
pub use ;