git_async/lib.rs
1//! An async-first Rust library for reading git repositories
2//!
3//! # Usage
4//!
5//! The main entry point is the [`Repo`] object, which represents a git
6//! repository. Refs and objects are looked up via methods on [`Repo`].
7//!
8//! The library is agnostic as to the async runtime in use, so consumers must
9//! implement a couple of traits that provide filesystem operations. See the
10//! [`file_system`] module for further details.
11//!
12//! For example, these could use Tokio, or the web filesystem API using
13//! wasm-bindgen's support for transforming JS promises to Rust futures. A dummy
14//! implementation could use the Rust standard library's synchronous filesystem
15//! operations.
16//!
17//! A future goal is to provide some standard implementations for commonly-used
18//! async runtimes.
19//!
20//! # Example
21//! ```
22//! # use git_async::Repo;
23//! # use git_async::error::GResult;
24//! # use git_async::file_system::{File, Directory, FileSystem, FileSystemError, Offset, DirEntry};
25//! # struct MyFile;
26//! # impl File for MyFile {
27//! # async fn read_all(&mut self) -> Result<Vec<u8>, FileSystemError> { unimplemented!() }
28//! # async fn read_segment(&mut self, _: Offset, _: &mut [u8]) -> Result<usize, FileSystemError> { unimplemented! () }
29//! # }
30//! # struct MyDirectory;
31//! # impl MyDirectory { fn new(s: &str) -> Self { unimplemented!() } }
32//! # impl Clone for MyDirectory { fn clone(&self) -> Self { unimplemented!() } }
33//! # impl Directory<MyFile> for MyDirectory {
34//! # async fn open_subdir(&self, _: &[u8]) -> Result<Self, FileSystemError> { unimplemented!() }
35//! # async fn list_dir(&self) -> Result<Vec<DirEntry>, FileSystemError> { unimplemented!() }
36//! # async fn open_file(&self, _: &[u8]) -> Result<MyFile, FileSystemError> { unimplemented!() }
37//! # }
38//! # struct MyFS;
39//! # impl FileSystem for MyFS {
40//! # type Directory = MyDirectory;
41//! # type File = MyFile;
42//! # }
43//! async fn example() -> GResult<()> {
44//! let repo = Repo::<MyFS>::open(MyDirectory::new("a-repository")).await?;
45//! let head = repo.head().await?;
46//! let commit = head.peel_to_commit(&repo).await?.unwrap();
47//! let message = commit.message();
48//! println!("{}", str::from_utf8(message).unwrap());
49//! Ok(())
50//! }
51//! ```
52//!
53//! # Caveats
54//! There are a few things this crate cannot (yet) do. They are in scope, so
55//! future versions may support them, but for now they are not implemented.
56//!
57//! - It only supports read operations on git repositories
58//! - It ignores the working tree. Only operations involving the actual
59//! repository structure are supported
60//! - The diff algorithm is naive and quite slow. I have not looked into how
61//! `git diff` manages to be so fast, but I imagine it uses the packfile delta
62//! encoding somehow to optimize diffing.
63
64#![cfg_attr(docsrs, feature(doc_cfg))]
65#![cfg_attr(doc, warn(missing_docs))]
66#![cfg_attr(not(test), no_std)]
67#![warn(clippy::pedantic)]
68#![allow(clippy::missing_errors_doc)]
69#![allow(clippy::enum_glob_use)]
70#![allow(clippy::must_use_candidate)]
71#![allow(clippy::missing_panics_doc)]
72#![cfg_attr(test, allow(clippy::cast_possible_truncation))]
73
74#[cfg(doc)]
75extern crate std;
76
77extern crate alloc;
78
79#[cfg(feature = "diff")]
80pub mod diff;
81pub mod error;
82pub mod file_system;
83pub mod object;
84pub mod reference;
85#[cfg(feature = "web")]
86pub mod web;
87
88mod object_store;
89mod parsing;
90mod repo;
91mod subslice_range;
92
93pub use repo::Repo;
94pub use repo::RepoConfig;
95
96#[cfg(test)]
97mod test;