Skip to content

Commit 4507f94

Browse files
committed
Merge branch 'consecutive-negotiation'
2 parents 78d28a7 + 56f4d30 commit 4507f94

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+890
-481
lines changed

Cargo.lock

Lines changed: 5 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,6 @@ members = [
253253
"cargo-smart-release",
254254
"tests/tools",
255255

256-
"gix-revision/tests",
257256
"gix-diff/tests",
258257
"gix-pack/tests",
259258
"gix-index/tests",

crate-status.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ Make it the best-performing implementation and the most convenient one.
469469

470470
### gix-revision
471471
* [x] `describe()` (similar to `git name-rev`)
472+
* [x] primitives to help with graph traversal, along with commit-graph acceleration.
472473
* parse specifications
473474
* [x] parsing and navigation
474475
* [x] revision ranges
@@ -638,7 +639,7 @@ See its [README.md](https://github.com/Byron/gitoxide/blob/main/gix-lock/README.
638639
* **Id**
639640
* [x] short hashes with detection of ambiguity.
640641
* **Commit**
641-
* [x] `describe()` like functionality
642+
* [x] `git describe` like functionality, with optional commit-graph acceleration
642643
* [x] create new commit from tree
643644
* **Objects**
644645
* [x] lookup

gitoxide-core/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,14 @@ async-client = ["gix/async-network-client-async-std", "gix-transport-configurati
3333

3434
#! ### Other
3535
## Data structures implement `serde::Serialize` and `serde::Deserialize`.
36-
serde = ["gix-commitgraph/serde", "gix/serde", "serde_json", "dep:serde", "bytesize/serde"]
36+
serde = ["gix/serde", "serde_json", "dep:serde", "bytesize/serde"]
3737

3838

3939
[dependencies]
4040
# deselect everything else (like "performance") as this should be controllable by the parent application.
4141
gix = { version = "^0.44.1", path = "../gix", default-features = false }
4242
gix-pack-for-configuration-only = { package = "gix-pack", version = "^0.35.0", path = "../gix-pack", default-features = false, features = ["pack-cache-lru-dynamic", "pack-cache-lru-static"] }
4343
gix-transport-configuration-only = { package = "gix-transport", version = "^0.31.0", path = "../gix-transport", default-features = false }
44-
gix-commitgraph = { version = "^0.14.0", path = "../gix-commitgraph" }
4544
serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] }
4645
anyhow = "1.0.42"
4746
thiserror = "1.0.34"

gitoxide-core/src/commitgraph/verify.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::{io, path::Path};
22

33
use anyhow::{Context as AnyhowContext, Result};
4-
use gix_commitgraph::{graph::verify::Outcome, Graph};
4+
use gix::commitgraph::Graph;
55

66
use crate::OutputFormat;
77

@@ -31,15 +31,15 @@ pub fn graph_or_file<W1, W2>(
3131
mut out,
3232
output_statistics,
3333
}: Context<W1, W2>,
34-
) -> Result<gix_commitgraph::graph::verify::Outcome>
34+
) -> Result<gix::commitgraph::verify::Outcome>
3535
where
3636
W1: io::Write,
3737
W2: io::Write,
3838
{
3939
let g = Graph::at(path).with_context(|| "Could not open commit graph")?;
4040

4141
#[allow(clippy::unnecessary_wraps, unknown_lints)]
42-
fn noop_processor(_commit: &gix_commitgraph::file::Commit<'_>) -> std::result::Result<(), std::fmt::Error> {
42+
fn noop_processor(_commit: &gix::commitgraph::file::Commit<'_>) -> std::result::Result<(), std::fmt::Error> {
4343
Ok(())
4444
}
4545
let stats = g
@@ -57,7 +57,7 @@ where
5757
Ok(stats)
5858
}
5959

60-
fn print_human_output(out: &mut impl io::Write, stats: &Outcome) -> io::Result<()> {
60+
fn print_human_output(out: &mut impl io::Write, stats: &gix::commitgraph::verify::Outcome) -> io::Result<()> {
6161
writeln!(out, "number of commits with the given number of parents")?;
6262
let mut parent_counts: Vec<_> = stats.parent_counts.iter().map(|(a, b)| (*a, *b)).collect();
6363
parent_counts.sort_by_key(|e| e.0);

gix-commitgraph/src/graph/access.rs renamed to gix-commitgraph/src/access.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
1-
use crate::{
2-
file::{self, Commit, File},
3-
graph::{self, Graph},
4-
};
1+
use crate::{file, file::Commit, File, Graph, Position};
52

63
/// Access
74
impl Graph {
85
/// Returns the commit at the given position `pos`.
96
///
107
/// # Panics
118
/// If `pos` is greater or equal to [`num_commits()`][Graph::num_commits()].
12-
pub fn commit_at(&self, pos: graph::Position) -> Commit<'_> {
9+
pub fn commit_at(&self, pos: Position) -> Commit<'_> {
1310
let r = self.lookup_by_pos(pos);
1411
r.file.commit_at(r.pos)
1512
}
@@ -24,7 +21,7 @@ impl Graph {
2421
///
2522
/// # Panics
2623
/// If `pos` is greater or equal to [`num_commits()`][Graph::num_commits()].
27-
pub fn id_at(&self, pos: graph::Position) -> &gix_hash::oid {
24+
pub fn id_at(&self, pos: Position) -> &gix_hash::oid {
2825
let r = self.lookup_by_pos(pos);
2926
r.file.id_at(r.pos)
3027
}
@@ -40,7 +37,7 @@ impl Graph {
4037
}
4138

4239
/// Translate the given `id` to its position in the file.
43-
pub fn lookup(&self, id: impl AsRef<gix_hash::oid>) -> Option<graph::Position> {
40+
pub fn lookup(&self, id: impl AsRef<gix_hash::oid>) -> Option<Position> {
4441
Some(self.lookup_by_id(id.as_ref())?.graph_pos)
4542
}
4643

@@ -59,15 +56,15 @@ impl Graph {
5956
return Some(LookupByIdResult {
6057
file,
6158
file_pos: lex_pos,
62-
graph_pos: graph::Position(current_file_start + lex_pos.0),
59+
graph_pos: Position(current_file_start + lex_pos.0),
6360
});
6461
}
6562
current_file_start += file.num_commits();
6663
}
6764
None
6865
}
6966

70-
fn lookup_by_pos(&self, pos: graph::Position) -> LookupByPositionResult<'_> {
67+
fn lookup_by_pos(&self, pos: Position) -> LookupByPositionResult<'_> {
7168
let mut remaining = pos.0;
7269
for (file_index, file) in self.files.iter().enumerate() {
7370
match remaining.checked_sub(file.num_commits()) {
@@ -88,7 +85,7 @@ impl Graph {
8885
#[derive(Clone)]
8986
struct LookupByIdResult<'a> {
9087
pub file: &'a File,
91-
pub graph_pos: graph::Position,
88+
pub graph_pos: Position,
9289
pub file_pos: file::Position,
9390
}
9491

gix-commitgraph/src/file/access.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ use std::{
44
path::Path,
55
};
66

7-
use crate::file::{self, commit::Commit, File, COMMIT_DATA_ENTRY_SIZE_SANS_HASH};
7+
use crate::{
8+
file::{self, commit::Commit, COMMIT_DATA_ENTRY_SIZE_SANS_HASH},
9+
File,
10+
};
811

912
/// Access
1013
impl File {

gix-commitgraph/src/file/commit.rs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use std::{
66
};
77

88
use crate::{
9-
file::{self, File, EXTENDED_EDGES_MASK, LAST_EXTENDED_EDGE_MASK, NO_PARENT},
10-
graph,
9+
file::{self, EXTENDED_EDGES_MASK, LAST_EXTENDED_EDGE_MASK, NO_PARENT},
10+
File, Position,
1111
};
1212

1313
/// The error used in the [`file::commit`][self] module.
@@ -25,6 +25,7 @@ pub enum Error {
2525
}
2626

2727
/// A commit as stored in a [`File`].
28+
#[derive(Copy, Clone)]
2829
pub struct Commit<'a> {
2930
file: &'a File,
3031
pos: file::Position,
@@ -72,11 +73,11 @@ impl<'a> Commit<'a> {
7273
}
7374

7475
/// Returns an iterator over the parent positions for lookup in the owning [Graph][crate::Graph].
75-
pub fn iter_parents(&'a self) -> impl Iterator<Item = Result<graph::Position, Error>> + 'a {
76+
pub fn iter_parents(self) -> Parents<'a> {
7677
// I didn't find a combinator approach that a) was as strict as ParentIterator, b) supported
7778
// fuse-after-first-error behavior, and b) was significantly shorter or more understandable
7879
// than ParentIterator. So here we are.
79-
ParentIterator {
80+
Parents {
8081
commit_data: self,
8182
state: ParentIteratorState::First,
8283
}
@@ -88,7 +89,7 @@ impl<'a> Commit<'a> {
8889
}
8990

9091
/// Returns the first parent of this commit.
91-
pub fn parent1(&self) -> Result<Option<graph::Position>, Error> {
92+
pub fn parent1(&self) -> Result<Option<Position>, Error> {
9293
self.iter_parents().next().transpose()
9394
}
9495

@@ -127,13 +128,13 @@ impl<'a> PartialEq for Commit<'a> {
127128
}
128129

129130
/// An iterator over parents of a [`Commit`].
130-
pub struct ParentIterator<'a> {
131-
commit_data: &'a Commit<'a>,
131+
pub struct Parents<'a> {
132+
commit_data: Commit<'a>,
132133
state: ParentIteratorState<'a>,
133134
}
134135

135-
impl<'a> Iterator for ParentIterator<'a> {
136-
type Item = Result<graph::Position, Error>;
136+
impl<'a> Iterator for Parents<'a> {
137+
type Item = Result<Position, Error>;
137138

138139
fn next(&mut self) -> Option<Self::Item> {
139140
let state = std::mem::replace(&mut self.state, ParentIteratorState::Exhausted);
@@ -221,7 +222,7 @@ enum ParentIteratorState<'a> {
221222
#[derive(Clone, Copy, Debug)]
222223
enum ParentEdge {
223224
None,
224-
GraphPosition(graph::Position),
225+
GraphPosition(Position),
225226
ExtraEdgeIndex(u32),
226227
}
227228

@@ -233,22 +234,22 @@ impl ParentEdge {
233234
if raw & EXTENDED_EDGES_MASK != 0 {
234235
ParentEdge::ExtraEdgeIndex(raw & !EXTENDED_EDGES_MASK)
235236
} else {
236-
ParentEdge::GraphPosition(graph::Position(raw))
237+
ParentEdge::GraphPosition(Position(raw))
237238
}
238239
}
239240
}
240241

241242
enum ExtraEdge {
242-
Internal(graph::Position),
243-
Last(graph::Position),
243+
Internal(Position),
244+
Last(Position),
244245
}
245246

246247
impl ExtraEdge {
247248
pub fn from_raw(raw: u32) -> Self {
248249
if raw & LAST_EXTENDED_EDGE_MASK != 0 {
249-
Self::Last(graph::Position(raw & !LAST_EXTENDED_EDGE_MASK))
250+
Self::Last(Position(raw & !LAST_EXTENDED_EDGE_MASK))
250251
} else {
251-
Self::Internal(graph::Position(raw))
252+
Self::Internal(Position(raw))
252253
}
253254
}
254255
}

gix-commitgraph/src/file/init.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@ use std::{
66
use bstr::ByteSlice;
77
use memmap2::Mmap;
88

9-
use crate::file::{
10-
ChunkId, File, BASE_GRAPHS_LIST_CHUNK_ID, COMMIT_DATA_CHUNK_ID, COMMIT_DATA_ENTRY_SIZE_SANS_HASH,
11-
EXTENDED_EDGES_LIST_CHUNK_ID, FAN_LEN, HEADER_LEN, OID_FAN_CHUNK_ID, OID_LOOKUP_CHUNK_ID, SIGNATURE,
9+
use crate::{
10+
file::{
11+
ChunkId, BASE_GRAPHS_LIST_CHUNK_ID, COMMIT_DATA_CHUNK_ID, COMMIT_DATA_ENTRY_SIZE_SANS_HASH,
12+
EXTENDED_EDGES_LIST_CHUNK_ID, FAN_LEN, HEADER_LEN, OID_FAN_CHUNK_ID, OID_LOOKUP_CHUNK_ID, SIGNATURE,
13+
},
14+
File,
1215
};
1316

1417
/// The error used in [`File::at()`].

gix-commitgraph/src/file/mod.rs

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
//! Operations on a single commit-graph file.
22
3-
use std::{
4-
fmt::{Display, Formatter},
5-
ops::Range,
6-
path::PathBuf,
7-
};
8-
9-
use memmap2::Mmap;
3+
use std::fmt::{Display, Formatter};
104

115
pub use self::{commit::Commit, init::Error};
126

@@ -16,7 +10,7 @@ mod init;
1610
pub mod verify;
1711

1812
const COMMIT_DATA_ENTRY_SIZE_SANS_HASH: usize = 16;
19-
const FAN_LEN: usize = 256;
13+
pub(crate) const FAN_LEN: usize = 256;
2014
const HEADER_LEN: usize = 8;
2115

2216
const SIGNATURE: &[u8] = b"CGPH";
@@ -34,31 +28,14 @@ const NO_PARENT: u32 = 0x7000_0000;
3428
const EXTENDED_EDGES_MASK: u32 = 0x8000_0000;
3529
const LAST_EXTENDED_EDGE_MASK: u32 = 0x8000_0000;
3630

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].
41-
pub 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: gix_hash::Kind,
52-
}
53-
5431
/// The position of a given commit within a graph file, starting at 0.
5532
///
56-
/// Commits within a graph file are sorted in lexicographical order by OID; a commit's lexigraphical position
33+
/// Commits within a graph file are sorted in lexicographical order by OID; a commit's lexicographical position
5734
/// 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.
35+
/// start at lexicographical position 0, so it is unique across a single file but is not unique across
36+
/// the whole commit graph. Each commit also has a graph position ([`Position`][crate::Position]),
37+
/// which is unique across the whole commit graph.
38+
/// In order to avoid accidentally mixing lexicographical positions with graph positions, distinct types are used for each.
6239
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
6340
pub struct Position(pub u32);
6441

gix-commitgraph/src/file/verify.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@ use std::{
55
path::Path,
66
};
77

8-
use crate::{
9-
file::{self, File},
10-
GENERATION_NUMBER_INFINITY, GENERATION_NUMBER_MAX,
11-
};
8+
use crate::{file, File, GENERATION_NUMBER_INFINITY, GENERATION_NUMBER_MAX};
129

1310
/// The error used in [`File::traverse()`].
1411
#[derive(thiserror::Error, Debug)]

0 commit comments

Comments
 (0)