git_commitgraph/file/
mod.rs

1//! Operations on a single commit-graph file.
2
3use std::{
4    fmt::{Display, Formatter},
5    ops::Range,
6    path::PathBuf,
7};
8
9use memmap2::Mmap;
10
11pub use self::{commit::Commit, init::Error};
12
13mod access;
14pub mod commit;
15mod init;
16pub mod verify;
17
18const COMMIT_DATA_ENTRY_SIZE_SANS_HASH: usize = 16;
19const FAN_LEN: usize = 256;
20const HEADER_LEN: usize = 8;
21
22const SIGNATURE: &[u8] = b"CGPH";
23
24type ChunkId = git_chunk::Id;
25const BASE_GRAPHS_LIST_CHUNK_ID: ChunkId = *b"BASE";
26const COMMIT_DATA_CHUNK_ID: ChunkId = *b"CDAT";
27const EXTENDED_EDGES_LIST_CHUNK_ID: ChunkId = *b"EDGE";
28const OID_FAN_CHUNK_ID: ChunkId = *b"OIDF";
29const OID_LOOKUP_CHUNK_ID: ChunkId = *b"OIDL";
30
31// Note that git's commit-graph-format.txt as of v2.28.0 gives an incorrect value 0x0700_0000 for
32// NO_PARENT. Fixed in https://github.com/git/git/commit/4d515253afcef985e94400adbfed7044959f9121 .
33const NO_PARENT: u32 = 0x7000_0000;
34const EXTENDED_EDGES_MASK: u32 = 0x8000_0000;
35const LAST_EXTENDED_EDGE_MASK: u32 = 0x8000_0000;
36
37/// A single commit-graph file.
38///
39/// All operations on a `File` are local to that graph file. Since a commit graph can span multiple
40/// files, all interesting graph operations belong on [`Graph`][crate::Graph].
41pub struct File {
42    base_graph_count: u8,
43    base_graphs_list_offset: Option<usize>,
44    commit_data_offset: usize,
45    data: Mmap,
46    extra_edges_list_range: Option<Range<usize>>,
47    fan: [u32; FAN_LEN],
48    oid_lookup_offset: usize,
49    path: PathBuf,
50    hash_len: usize,
51    object_hash: git_hash::Kind,
52}
53
54/// The position of a given commit within a graph file, starting at 0.
55///
56/// Commits within a graph file are sorted in lexicographical order by OID; a commit's lexigraphical position
57/// is its position in this ordering. If a commit graph spans multiple files, each file's commits
58/// start at lexigraphical position 0, so it is unique across a single file but is not unique across
59/// the whole commit graph. Each commit also has a graph position ([`graph::Position`][crate::graph::Position]),
60/// which is unique /// across the whole commit graph. In order to avoid accidentally mixing lexigraphical positions with graph
61/// positions, distinct types are used for each.
62#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
63pub struct Position(pub u32);
64
65impl Display for Position {
66    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
67        self.0.fmt(f)
68    }
69}