Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
4.1 kB · 114 lines
Rust
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115//! Read, verify, and traverse git commit graphs.//!//! A [commit graph][Graph] is an index of commits in the git commit history.//! The [Graph] stores commit data in a way that accelerates lookups considerably compared to//! traversing the git history by usual means.//!//! As generating the full commit graph from scratch can take some time, git may write new commits//! to separate [files][File] instead of overwriting the original file.//! Eventually, git will merge these files together as the number of files grows.//! ## Feature Flags#![cfg_attr( all(doc, feature = "document-features"), doc = ::document_features::document_features!())]#![cfg_attr(all(doc, feature = "document-features"), feature(doc_cfg))]#![deny(missing_docs, unsafe_code)]
use gix_error::{Exn, Message};use std::path::Path;
/// A single commit-graph file.////// All operations on a `File` are local to that graph file. Since a commit graph can span multiple/// files, all interesting graph operations belong on [`Graph`].pub struct File { base_graph_count: u8, base_graphs_list_offset: Option<usize>, bloom_filter_data_len: usize, bloom_filter_data_offset: Option<usize>, bloom_filter_index_offset: Option<usize>, bloom_filter_settings: Option<BloomFilterSettings>, commit_data_offset: usize, data: memmap2::Mmap, extra_edges_list_range: Option<std::ops::Range<usize>>, fan: [u32; file::FAN_LEN], generation_data_offset: Option<usize>, generation_data_overflow_range: Option<std::ops::Range<usize>>, /// `false` if generation data is present but unusable because another file in the graph lacks it. read_generation_data: bool, oid_lookup_offset: usize, path: std::path::PathBuf, hash_len: usize, object_hash: gix_hash::Kind,}
/// Bloom filter parameters as stored in a commit-graph `BDAT` chunk header.#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]pub struct BloomFilterSettings { /// Version of the hash algorithm used by changed-path Bloom filters. pub hash_version: u32, /// Number of hashes computed for each key. pub num_hashes: u32, /// Number of bits per Bloom filter entry. pub bits_per_entry: u32,}
impl BloomFilterSettings { pub(crate) fn is_supported(&self) -> bool { match self.hash_version { // v1 is deprecated, but existing graphs still use it. 1 | 2 => true, _ => false, } }}
/// A complete commit graph.////// The data in the commit graph may come from a monolithic `objects/info/commit-graph` file, or it/// may come from one or more `objects/info/commit-graphs/graph-*.graph` files. These files are/// generated via `git commit-graph write ...` commands.pub struct Graph { files: nonempty::NonEmpty<File>,}
/// Instantiate a commit graph from an `.git/objects/info` directory, or one of the various commit-graph files.pub fn at(path: impl AsRef<Path>) -> Result<Graph, Exn<Message>> { Graph::at(path.as_ref())}
mod access;pub mod bloom;pub mod file;///pub mod init;pub mod verify;pub mod write;
/// The number of generations that are considered 'infinite' commit history.pub const GENERATION_NUMBER_INFINITY: u32 = 0xffff_ffff;/// The largest valid generation number.////// If a commit's real generation number is larger than this, the commit graph will cap the value to/// this number./// The largest distinct generation number is `GENERATION_NUMBER_MAX - 1`.pub const GENERATION_NUMBER_MAX: u32 = 0x3fff_ffff;
/// The maximum number of commits that can be stored in a commit graph.pub const MAX_COMMITS: u32 = (1 << 30) + (1 << 29) + (1 << 28) - 1;
#[inline]pub(crate) fn from_be_u32(b: &[u8]) -> u32 { u32::from_be_bytes(b.try_into().unwrap())}
/// A generalized position for use in [`Graph`].#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]pub struct Position(pub u32);
impl std::fmt::Display for Position { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.0.fmt(f) }}