Skip to content

Commit ff8d42a

Browse files
committed
bring back the no-repo commitgraph for stress-tests to work
1 parent 750b07a commit ff8d42a

File tree

5 files changed

+125
-3
lines changed

5 files changed

+125
-3
lines changed

Diff for: gitoxide-core/src/commitgraph/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pub mod verify;
2+
pub use verify::function::verify;

Diff for: gitoxide-core/src/commitgraph/verify.rs

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
use crate::OutputFormat;
2+
3+
/// A general purpose context for many operations provided here
4+
pub struct Context<W1: std::io::Write, W2: std::io::Write> {
5+
/// A stream to which to output errors
6+
pub err: W2,
7+
/// A stream to which to output operation results
8+
pub out: W1,
9+
pub output_statistics: Option<OutputFormat>,
10+
}
11+
12+
impl Default for Context<Vec<u8>, Vec<u8>> {
13+
fn default() -> Self {
14+
Context {
15+
err: Vec::new(),
16+
out: Vec::new(),
17+
output_statistics: None,
18+
}
19+
}
20+
}
21+
22+
pub(crate) mod function {
23+
use crate::OutputFormat;
24+
use anyhow::{Context as AnyhowContext, Result};
25+
use gix::commitgraph::{verify::Outcome, Graph};
26+
use std::{io, path::Path};
27+
28+
pub fn verify<W1, W2>(
29+
path: impl AsRef<Path>,
30+
super::Context {
31+
err: _err,
32+
mut out,
33+
output_statistics,
34+
}: super::Context<W1, W2>,
35+
) -> Result<gix::commitgraph::verify::Outcome>
36+
where
37+
W1: io::Write,
38+
W2: io::Write,
39+
{
40+
let g = Graph::at(path).with_context(|| "Could not open commit graph")?;
41+
42+
#[allow(clippy::unnecessary_wraps, unknown_lints)]
43+
fn noop_processor(_commit: &gix::commitgraph::file::Commit<'_>) -> std::result::Result<(), std::fmt::Error> {
44+
Ok(())
45+
}
46+
let stats = g
47+
.verify_integrity(noop_processor)
48+
.with_context(|| "Verification failure")?;
49+
50+
#[cfg_attr(not(feature = "serde"), allow(clippy::single_match))]
51+
match output_statistics {
52+
Some(OutputFormat::Human) => drop(print_human_output(&mut out, &stats)),
53+
#[cfg(feature = "serde")]
54+
Some(OutputFormat::Json) => serde_json::to_writer_pretty(out, &stats)?,
55+
_ => {}
56+
}
57+
58+
Ok(stats)
59+
}
60+
61+
fn print_human_output(out: &mut impl io::Write, stats: &Outcome) -> io::Result<()> {
62+
writeln!(out, "number of commits with the given number of parents")?;
63+
let mut parent_counts: Vec<_> = stats.parent_counts.iter().map(|(a, b)| (*a, *b)).collect();
64+
parent_counts.sort_by_key(|e| e.0);
65+
for (parent_count, commit_count) in parent_counts.into_iter() {
66+
writeln!(out, "\t{parent_count:>2}: {commit_count}")?;
67+
}
68+
writeln!(out, "\t->: {}", stats.num_commits)?;
69+
70+
write!(out, "\nlongest path length between two commits: ")?;
71+
if let Some(n) = stats.longest_path_length {
72+
writeln!(out, "{n}")?;
73+
} else {
74+
writeln!(out, "unknown")?;
75+
}
76+
77+
Ok(())
78+
}
79+
}

Diff for: gitoxide-core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ impl FromStr for OutputFormat {
6363
}
6464
}
6565

66+
pub mod commitgraph;
6667
pub mod net;
6768

6869
#[cfg(feature = "estimate-hours")]

Diff for: src/plumbing/main.rs

+23-3
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,11 @@ use gitoxide_core as core;
1313
use gitoxide_core::pack::verify;
1414
use gix::bstr::io::BufReadExt;
1515

16-
use crate::plumbing::options::commitgraph;
1716
use crate::{
1817
plumbing::{
1918
options::{
20-
attributes, commit, config, credential, exclude, free, index, mailmap, odb, revision, tree, Args,
21-
Subcommands,
19+
attributes, commit, commitgraph, config, credential, exclude, free, index, mailmap, odb, revision, tree,
20+
Args, Subcommands,
2221
},
2322
show_progress,
2423
},
@@ -303,6 +302,27 @@ pub fn main() -> Result<()> {
303302
)
304303
.map(|_| ()),
305304
Subcommands::Free(subcommands) => match subcommands {
305+
free::Subcommands::CommitGraph(cmd) => match cmd {
306+
free::commitgraph::Subcommands::Verify { path, statistics } => prepare_and_run(
307+
"commitgraph-verify",
308+
auto_verbose,
309+
progress,
310+
progress_keep_open,
311+
None,
312+
move |_progress, out, err| {
313+
let output_statistics = if statistics { Some(format) } else { None };
314+
core::commitgraph::verify(
315+
path,
316+
core::commitgraph::verify::Context {
317+
err,
318+
out,
319+
output_statistics,
320+
},
321+
)
322+
},
323+
)
324+
.map(|_| ()),
325+
},
306326
free::Subcommands::Index(free::index::Platform {
307327
object_hash,
308328
index_path,

Diff for: src/plumbing/options/free.rs

+20
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#[derive(Debug, clap::Subcommand)]
22
#[clap(visible_alias = "no-repo")]
33
pub enum Subcommands {
4+
/// Subcommands for interacting with commit-graphs
5+
#[clap(subcommand)]
6+
CommitGraph(commitgraph::Subcommands),
47
/// Subcommands for interacting with mailmaps
58
Mailmap {
69
#[clap(flatten)]
@@ -13,6 +16,23 @@ pub enum Subcommands {
1316
Index(index::Platform),
1417
}
1518

19+
///
20+
pub mod commitgraph {
21+
use std::path::PathBuf;
22+
23+
#[derive(Debug, clap::Subcommand)]
24+
pub enum Subcommands {
25+
/// Verify the integrity of a commit graph
26+
Verify {
27+
/// The path to '.git/objects/info/', '.git/objects/info/commit-graphs/', or '.git/objects/info/commit-graph' to validate.
28+
path: PathBuf,
29+
/// output statistical information about the pack
30+
#[clap(long, short = 's')]
31+
statistics: bool,
32+
},
33+
}
34+
}
35+
1636
pub mod index {
1737
use std::path::PathBuf;
1838

0 commit comments

Comments
 (0)