Skip to main content

grit_lib/
lib.rs

1#![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used))]
2#![deny(missing_docs)]
3#![warn(rustdoc::unescaped_backticks)]
4
5//! grit-lib — fast, linkable Git engine for Rust.
6//!
7//! # Minimum Rust version
8//!
9//! The published crate requires **Rust 1.95** or newer (`rust-version` in
10//! [`Cargo.toml`](https://github.com/gitbutlerapp/grit/blob/main/grit-lib/Cargo.toml)).
11//! Contributors building the Grit workspace use the pinned toolchain in
12//! [`rust-toolchain.toml`](https://github.com/gitbutlerapp/grit/blob/main/rust-toolchain.toml)
13//! (currently 1.99.0); that pin does not apply when you depend on `grit-lib`
14//! from crates.io outside the repo.
15//!
16//! Grit reimplements Git's on-disk formats and wire protocols in idiomatic Rust
17//! so embedders can open repositories, walk history, diff, merge, fetch, and push
18//! without shelling out to the `git` binary. The [`grit`](https://github.com/gitbutlerapp/grit)
19//! CLI is a thin presentation layer over this crate; almost all behavior lives here.
20//!
21//! # Getting started
22//!
23//! [`Repository`](repo::Repository) is the primary entry point: discover or open a
24//! work tree, then use methods and focused modules for objects, refs, the index,
25//! config, remotes, and porcelain operations.
26//!
27//! ```
28//! use grit_lib::config::environment::RepositoryOptions;
29//! use grit_lib::repo::{InitOptions, Repository};
30//! use grit_lib::state::resolve_head;
31//!
32//! # fn main() -> grit_lib::error::Result<()> {
33//! let dir = tempfile::tempdir()?;
34//! let repo = Repository::init(dir.path(), &InitOptions::default())?;
35//! let head = resolve_head(repo.git_dir())?;
36//! assert!(matches!(head, grit_lib::state::HeadState::Branch { short_name, oid: None, .. } if short_name == "main"));
37//! let _ = Repository::open(
38//!     repo.git_dir(),
39//!     &RepositoryOptions::empty().with_work_tree(dir.path()),
40//! )?;
41//! # Ok(())
42//! # }
43//! ```
44//!
45//! - [`Repository`](repo::Repository) exposes typed handles for objects, refs, the
46//!   index, config, revision walking, and diffs ([`objects::Objects`],
47//!   [`refs::References`], [`index::IndexHandle`],
48//!   [`config::ConfigHandle`], [`revwalk::RevWalk`],
49//!   [`diff::Diff`]), plus [`repo_handles`] for remotes, worktrees, stash,
50//!   notes, reflogs, and bundles.
51//! - [`prelude`] re-exports the types most call sites need.
52//! - [`porcelain`] holds user-facing operations that return structured result
53//!   *models* (the CLI renders them).
54//! - Browse the engine by domain: [`objects`], [`refs`], [`index`], [`revwalk`],
55//!   [`diff`], [`config`], [`remote`], [`worktree`], [`stash`], [`notes`], and
56//!   [`bundle`]. Legacy flat paths (`grit_lib::odb`, `grit_lib::fetch`, …) are
57//!   private; [grit-scm.com/docs/library/api-layout](https://grit-scm.com/docs/library/api-layout)
58//!   maps each old path to its canonical replacement.
59//! - [`progress`] defines how long-running operations report progress and
60//!   observe cancellation without touching the terminal.
61//!
62//! # API layout (canonical domains)
63//!
64//! | Flat path | Canonical path |
65//! | --- | --- |
66//! | `odb`, `pack`, `midx`, `hash`, `pack_bitmap`, `bitmap_walk`, … | [`objects`] |
67//! | `reflog`, `refspec`, `reftable`, `check_ref_format`, … | [`refs`] |
68//! | `sparse_checkout`, `split_index`, `untracked_cache`, `resolve_undo`, … | [`index`] |
69//! | `rev_list`, `rev_parse`, `merge_base`, `commit_graph_file`, … | [`revwalk`] |
70//! | `bloom`, `patch_ids`, `merge_trees`, `rerere`, … | [`diff`] |
71//! | `dotfile`, `ident`, `init_filesystem`, … | [`config`] |
72//! | `fetch`, `push`, `transport`, `credentials`, … | [`remote`] |
73//! | `ignore`, `attributes`, `pathspec`, … | [`worktree`] |
74//! | porcelain stash types | [`stash`] |
75//! | `bundle_remote` | [`bundle`] |
76//! | `parallel` | [`parallel`] (root) |
77//! | `repo`, `error`, `porcelain`, `progress`, … | root (unchanged) |
78//!
79//! # Porcelain
80//!
81//! [`porcelain`] implements user-facing workflows (`status`, `log`, `merge`, …) as
82//! pure functions that return structured result models. The library/CLI contract
83//! is documented in [`porcelain`]: options in, models out, progress via
84//! [`ProgressSink`](progress::ProgressSink) — no terminal I/O in the library.
85//!
86//! # Storage and refs
87//!
88//! - **Object database ([`objects`])** — loose objects plus pack files, pack indexes,
89//!   multi-pack-index (MIDX), delta chains, and promisor/partial clone hooks.
90//!   Backends are pluggable via the ODB abstraction on [`objects::Objects`].
91//! - **References ([`refs`])** — loose files, `packed-refs`, and reftable stacks;
92//!   reflog read/write and ref storage format selection live in the same module.
93//!   [`RefStorageFormat`] selects the on-disk ref layout at init.
94//!
95//! # Network and bundles
96//!
97//! [`remote`] implements fetch, push, and ls-remote over local paths, git/ssh URLs,
98//! and (with the optional HTTP client) smart HTTP. [`bundle`] reads and writes Git
99//! bundle files and bundle-related transport helpers.
100//!
101//! # Features
102//!
103//! | Feature | Default | Description |
104//! | ------- | ------- | ----------- |
105//! | *(none)* | — | Core library: ODB, refs, index, diff, merge, local transport |
106//! | `http-ureq` | disabled | [`ureq`](https://docs.rs/ureq) HTTP client for smart-HTTP fetch/push (rustls) |
107//! | `http-ureq-native-tls` | disabled | Platform TLS for `http-ureq` (Secure Transport on macOS); use instead of rustls on Apple targets |
108//!
109//! Enable HTTP in `Cargo.toml`:
110//!
111//! ```toml
112//! grit-lib = { version = "0.1", features = ["http-ureq"] }
113//! ```
114//!
115//! # Errors and progress
116//!
117//! [`error`] defines typed failures with `thiserror`. Long-running work accepts a
118//! [`ProgressSink`](progress::ProgressSink) and optional cancellation; see [`progress`].
119//!
120//! # Scope
121//!
122//! Modules tied to removed Git-compatible CLI surface are documented in
123//! `docs/v1-scope.md`. Compatibility means **formats and protocols**, validated in
124//! tests against the system `git` binary — not argv or message strings.
125
126// --- Curated public API: domain roots and cross-cutting modules only.
127// Flat implementation modules are `pub(crate)`; use canonical domain paths. ---
128pub mod porcelain;
129pub mod progress;
130
131/// The types most callers need, re-exported for `use grit_lib::prelude::*;`.
132///
133/// Library guide: [embedding](https://grit-scm.com/docs/library/embedding)
134///
135/// ```rust
136/// use grit_lib::prelude::*;
137/// use grit_lib::repo::InitOptions;
138///
139/// # fn main() -> Result<()> {
140/// let dir = tempfile::tempdir()?;
141/// let repo = Repository::init(dir.path(), &InitOptions::default())?;
142/// let _cfg = repo.config()?;
143/// assert!(repo.refs().read_raw("HEAD")?.is_some());
144/// # Ok(())
145/// # }
146/// ```
147pub mod prelude {
148    pub use crate::command_runner::{CommandRunner, RecordingRunner, SystemCommandRunner};
149    pub use crate::config::ConfigSet;
150    pub use crate::diagnostics::{
151        CollectingDiagnostics, DiagnosticSink, NullDiagnostics, Trace, Warning,
152    };
153    pub use crate::environment::{Environment, RepositoryOptions};
154    pub use crate::error::{Error, MidxError, Result};
155    pub use crate::index::Index;
156    pub use crate::objects::odb::Odb;
157    pub use crate::objects::{Object, ObjectId, ObjectInfo, ObjectKind};
158    pub use crate::repo::{
159        resolve_initial_branch, DiscoveryInfo, InitOptions, InitOutcome, Repository,
160        RepositoryBuilder,
161    };
162}
163
164pub mod revwalk;
165pub mod stash;
166
167pub mod apply;
168pub(crate) mod attributes;
169pub mod blame;
170pub(crate) mod bloom;
171pub(crate) mod branch_inventory;
172pub(crate) mod branch_tracking;
173pub mod bundle;
174pub(crate) mod bundle_remote;
175pub(crate) mod bundle_uri;
176pub mod change_id;
177pub(crate) mod check_ref_format;
178pub(crate) mod clone;
179pub(crate) mod combined_diff_patch;
180pub(crate) mod combined_tree_diff;
181pub mod command_runner;
182pub mod commit;
183pub(crate) mod commit_encoding;
184pub(crate) mod commit_graph_file;
185pub(crate) mod commit_graph_write;
186pub(crate) mod commit_pretty;
187pub(crate) mod commit_trailers;
188pub mod config;
189pub(crate) mod connectivity;
190pub(crate) mod credentials;
191pub(crate) mod crlf;
192pub(crate) mod delta_encode;
193pub(crate) mod delta_islands;
194pub(crate) mod delta_search;
195pub mod diagnostics;
196pub mod diff;
197pub(crate) mod diff_indent_heuristic;
198mod diff_rename_parallel;
199pub(crate) mod dotfile;
200pub(crate) mod environment;
201pub mod error;
202mod ewah_bitmap;
203pub(crate) mod git_dir;
204pub mod gitbutler;
205pub(crate) mod github_auth;
206pub(crate) mod grit_server_auth;
207pub(crate) mod line_interner;
208pub mod line_range;
209mod oid_abbrev;
210pub(crate) mod oid_abbrev_cache;
211pub(crate) mod pack_roll_delta;
212pub(crate) mod partial_clone;
213
214#[path = "bench_fixture/mod.rs"]
215mod bench_fixture_root;
216pub(crate) mod bitmap_walk;
217pub(crate) mod fetch;
218pub(crate) mod fetch_head;
219pub(crate) mod fetch_negotiator;
220mod fetch_request;
221pub(crate) mod filter_process;
222pub(crate) mod fmt_merge_msg;
223pub(crate) mod fs_publish;
224pub(crate) mod fs_readonly;
225pub(crate) mod fsck;
226pub(crate) mod fsck_msg_policy;
227pub(crate) mod fsck_standalone;
228#[path = "fsmonitor.rs"]
229mod fsmonitor_root;
230pub(crate) mod gc;
231pub(crate) mod git_binary_base85;
232pub(crate) mod git_date;
233pub(crate) mod git_path;
234pub(crate) mod gitmodules;
235pub(crate) mod hash;
236pub(crate) mod hide_refs;
237#[path = "history/mod.rs"]
238mod history_root;
239pub(crate) use history_root as history;
240pub(crate) mod alternate_boundary;
241pub(crate) mod atomic_replace;
242pub(crate) mod hooks;
243pub mod ident;
244pub(crate) mod ident_config;
245pub(crate) mod ident_resolve;
246pub(crate) mod ignore;
247pub mod index;
248mod index_eoie_ieot;
249pub(crate) mod index_name_hash_lazy;
250pub(crate) mod index_pack;
251pub(crate) mod init_filesystem;
252pub(crate) mod interpret_trailers;
253pub mod list_limit;
254pub(crate) mod local_object_copy;
255pub mod lockfile;
256pub(crate) mod log_walk;
257pub(crate) mod mailmap;
258pub mod maintenance;
259pub(crate) mod mem_pipe;
260pub(crate) mod merge_base;
261pub(crate) mod merge_diff;
262pub(crate) mod merge_driver;
263pub(crate) mod merge_file;
264pub(crate) mod merge_trees;
265pub(crate) mod midx;
266pub(crate) mod midx_error;
267pub(crate) mod net_trace;
268pub mod notes;
269#[path = "object_inspect.rs"]
270mod object_inspect_root;
271pub mod objects;
272pub(crate) mod odb;
273pub(crate) mod offload;
274pub mod operation;
275pub(crate) mod pack;
276pub(crate) mod pack_bitmap;
277mod pack_delta;
278mod pack_delta_walk;
279mod pack_fsck_verify;
280mod pack_index;
281pub(crate) mod pack_index_build;
282mod pack_map;
283pub(crate) mod pack_name_hash;
284pub(crate) mod pack_object_select;
285pub(crate) mod pack_objects;
286pub(crate) mod pack_receive;
287#[path = "pack_reuse.rs"]
288mod pack_reuse_root;
289pub(crate) mod pack_rev;
290pub(crate) mod pack_store;
291pub(crate) mod pack_stream_scan;
292mod pack_thin_bases;
293#[path = "pack_write.rs"]
294mod pack_write_root;
295pub(crate) mod pack_zlib;
296pub mod parallel;
297pub(crate) mod patch_ids;
298pub(crate) mod path_icase;
299pub(crate) mod path_population;
300pub mod path_validate;
301pub mod pathspec;
302pub(crate) mod pkt_line;
303pub(crate) mod precompose_config;
304pub(crate) mod promisor;
305pub(crate) mod promisor_fetch;
306pub(crate) mod promisor_remote;
307pub(crate) mod protocol;
308pub(crate) mod protocol_v2;
309pub(crate) mod prune_packed;
310pub(crate) mod push;
311pub(crate) mod push_bundle;
312pub(crate) mod push_report;
313#[path = "quote_path.rs"]
314mod quote_path_root;
315mod read_dir_kind;
316pub(crate) mod receive_pack;
317pub(crate) mod receive_quarantine;
318pub(crate) mod ref_exclusions;
319pub(crate) mod ref_namespace;
320pub(crate) mod ref_storage;
321pub(crate) mod reflog;
322pub mod refs;
323pub(crate) mod refs_fsck;
324pub(crate) mod refspec;
325pub(crate) mod reftable;
326pub mod remote;
327pub(crate) mod repack_pack;
328pub mod repo;
329pub(crate) mod repo_caches;
330pub mod repo_handles;
331#[doc(hidden)]
332pub mod repo_relpath;
333pub(crate) mod rerere;
334pub(crate) mod resolve_undo;
335pub(crate) mod resumable;
336pub(crate) mod rev_list;
337pub(crate) mod rev_list_error;
338pub(crate) mod rev_parse;
339pub(crate) mod rev_parse_error;
340pub(crate) mod serve;
341pub(crate) mod shallow;
342pub(crate) mod shared_repo;
343pub(crate) mod sideband_lines;
344pub(crate) mod signing;
345pub(crate) mod snapshot_checkout;
346pub(crate) mod sparse_checkout;
347pub(crate) mod split_index;
348pub mod state;
349pub(crate) mod stripspace;
350pub(crate) mod submodule_gitdir;
351pub(crate) mod terminal;
352pub(crate) mod textconv_cache;
353pub(crate) mod trace;
354mod tracked_path_tree;
355pub(crate) mod transfer;
356pub(crate) mod transport;
357pub(crate) mod transport_path;
358pub mod tree_sha256;
359pub(crate) mod unicode_normalization;
360pub(crate) mod unpack_objects;
361pub(crate) mod untracked_cache;
362pub(crate) mod upload_filter;
363pub(crate) mod url_rewrite;
364pub(crate) mod userdiff;
365pub(crate) mod wildmatch;
366pub mod worktree;
367mod worktree_batch;
368pub(crate) mod worktree_cwd;
369pub(crate) mod worktree_ref;
370pub(crate) mod worktree_rules;
371mod worktree_rules_tests;
372mod worktree_scan;
373pub use crate::hooks::{HookName, PostOperationHooks};
374pub use worktree_scan::PARALLEL_STAT_MIN_ENTRIES;
375#[doc(hidden)]
376pub use worktree_scan::{
377    reset_worktree_metadata_probe, worktree_metadata_probe_count, worktree_path_resolve_probe_count,
378};
379pub(crate) mod write_tree;
380pub(crate) mod ws;
381pub(crate) mod zlib_inflate;
382
383#[doc(hidden)]
384pub mod fuzz;
385
386pub use ref_storage::RefStorageFormat;
387
388pub use crate::oid_abbrev::OidAbbrevBatch;
389pub use objects::bench_fixture;
390pub use objects::pack_reuse;
391pub use objects::pack_write;
392pub use porcelain::quote_path;
393pub use revwalk::object_inspect;
394pub use worktree::fsmonitor;
395
396#[cfg(feature = "unstable-bench-helpers")]
397pub use pack_receive::{read_sideband_pack_to, PackReceiveTarget};
398
399#[cfg(test)]
400pub(crate) mod hot_path_test_metrics;
401
402#[cfg(test)]
403mod object_write_regression;
404#[cfg(test)]
405mod repository_config_snapshot_tests;
406#[cfg(test)]
407mod status_clean_tree_regression;