1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use std::{path::PathBuf, sync::atomic::AtomicBool};
use git_repository as git;
use git_repository::Progress;
use crate::{pack, OutputFormat};
pub struct Context {
pub output_statistics: Option<OutputFormat>,
pub thread_limit: Option<usize>,
pub verify_mode: pack::verify::Mode,
pub algorithm: pack::verify::Algorithm,
}
pub const PROGRESS_RANGE: std::ops::RangeInclusive<u8> = 1..=3;
pub fn integrity(
repo: PathBuf,
mut out: impl std::io::Write,
progress: impl Progress,
should_interrupt: &AtomicBool,
Context {
output_statistics,
thread_limit,
verify_mode,
algorithm,
}: Context,
) -> anyhow::Result<()> {
let repo = git_repository::open(repo)?;
#[cfg_attr(not(feature = "serde1"), allow(unused))]
let mut outcome = repo.objects.store_ref().verify_integrity(
progress,
should_interrupt,
git_repository::odb::pack::index::verify::integrity::Options {
verify_mode,
traversal: algorithm.into(),
thread_limit,
make_pack_lookup_cache: || git_repository::odb::pack::cache::Never,
},
)?;
if let Some(index) = repo.load_index().transpose()? {
index.verify_integrity()?;
index.verify_entries()?;
index.verify_extensions(true, {
use git::odb::FindExt;
let objects = repo.objects;
move |oid, buf: &mut Vec<u8>| objects.find_tree_iter(oid, buf).ok()
})?;
outcome.progress.info(format!("Index at '{}' OK", index.path.display()));
}
match output_statistics {
Some(OutputFormat::Human) => writeln!(out, "Human output is currently unsupported, use JSON instead")?,
#[cfg(feature = "serde1")]
Some(OutputFormat::Json) => {
serde_json::to_writer_pretty(
out,
&serde_json::json!({
"index_statistics" : outcome.index_statistics,
"loose_object-stores" : outcome.loose_object_stores
}),
)?;
}
None => {}
}
Ok(())
}