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//! ```
23//! # use git_async::Repo;
24//! # use git_async::error::GResult;
25//! # use git_async::file_system::{File, Directory, FileSystem, FileSystemError, Offset, DirEntry};
26//! # struct MyFile;
27//! # impl File for MyFile {
28//! # async fn read_all(&mut self) -> Result<Vec<u8>, FileSystemError> { unimplemented!() }
29//! # async fn read_segment(&mut self, _: Offset, _: &mut [u8]) -> Result<usize, FileSystemError> { unimplemented! () }
30//! # }
31//! # struct MyDirectory;
32//! # impl MyDirectory { fn new(s: &str) -> Self { unimplemented!() } }
33//! # impl Clone for MyDirectory { fn clone(&self) -> Self { unimplemented!() } }
34//! # impl Directory<MyFile> for MyDirectory {
35//! # async fn open_subdir(&self, _: &[u8]) -> Result<Self, FileSystemError> { unimplemented!() }
36//! # async fn list_dir(&self) -> Result<Vec<DirEntry>, FileSystemError> { unimplemented!() }
37//! # async fn open_file(&self, _: &[u8]) -> Result<MyFile, FileSystemError> { unimplemented!() }
38//! # }
39//! # struct MyFS;
40//! # impl FileSystem for MyFS {
41//! # type Directory = MyDirectory;
42//! # type File = MyFile;
43//! # }
44//! async fn example() -> GResult<()> {
45//! let repo = Repo::<MyFS>::open(MyDirectory::new("a-repository")).await?;
46//! let head = repo.head().await?;
47//! let commit = head.peel_to_commit(&repo).await?.unwrap();
48//! let message = commit.message();
49//! println!("{}", str::from_utf8(message).unwrap());
50//! Ok(())
51//! }
52//! ```
53//!
54//! # Caveats
55//!
56//! There are a few things this crate cannot (yet) do. They are in scope, so
57//! future versions may support them, but for now they are not implemented.
58//!
59//! - It only supports read operations on git repositories
60//! - It ignores the working tree. Only operations involving the actual
61//! repository structure are supported
62//! - The diff algorithm is naive and quite slow. I have not looked into how
63//! `git diff` manages to be so fast, but I imagine it uses the packfile delta
64//! encoding somehow to optimize diffing.
65
66#![cfg_attr(docsrs, feature(doc_cfg))]
67#![cfg_attr(doc, warn(missing_docs))]
68#![cfg_attr(not(test), no_std)]
69#![warn(clippy::pedantic)]
70#![allow(clippy::missing_errors_doc)]
71#![allow(clippy::enum_glob_use)]
72#![allow(clippy::must_use_candidate)]
73#![allow(clippy::missing_panics_doc)]
74#![cfg_attr(test, allow(clippy::cast_possible_truncation))]
75
76#[cfg(doc)]
77extern crate std;
78
79extern crate alloc;
80
81#[cfg(feature = "diff")]
82pub mod diff;
83pub mod error;
84pub mod file_system;
85pub mod object;
86pub mod reference;
87#[cfg(feature = "web")]
88pub mod web;
89
90mod object_store;
91mod parsing;
92mod repo;
93mod subslice_range;
94
95pub use repo::Repo;
96pub use repo::RepoConfig;
97
98#[cfg(test)]
99mod test;