Skip to content

Commit 80a4a7a

Browse files
committed
Very rough version of repository verification (#287)
1 parent 53d835a commit 80a4a7a

File tree

15 files changed

+128
-39
lines changed

15 files changed

+128
-39
lines changed

Diff for: git-hash/src/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66

77
mod borrowed;
88

9-
use std::convert::TryFrom;
10-
use std::str::FromStr;
9+
use std::{convert::TryFrom, str::FromStr};
1110

1211
pub use borrowed::oid;
1312

Diff for: git-odb/src/store_impls/dynamic/verify.rs

+17-7
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,25 @@
1-
use crate::pack;
2-
use crate::store::verify::integrity::{IndexStatistics, SingleOrMultiStatistics};
3-
use crate::types::IndexAndPacks;
1+
use std::{
2+
ops::Deref,
3+
sync::atomic::{AtomicBool, Ordering},
4+
};
5+
46
use git_features::progress::Progress;
5-
use std::ops::Deref;
6-
use std::sync::atomic::{AtomicBool, Ordering};
7+
8+
use crate::{
9+
pack,
10+
store::verify::integrity::{IndexStatistics, SingleOrMultiStatistics},
11+
types::IndexAndPacks,
12+
};
713

814
///
915
pub mod integrity {
10-
use crate::pack;
1116
use std::path::PathBuf;
1217

18+
use crate::pack;
19+
20+
/// Options for use in [`Store::verify_integrity()`][crate::Store::verify_integrity()].
21+
pub type Options<F> = pack::index::verify::integrity::Options<F>;
22+
1323
/// Returned by [`Store::verify_integrity()`][crate::Store::verify_integrity()].
1424
#[derive(Debug, thiserror::Error)]
1525
#[allow(missing_docs)]
@@ -81,7 +91,7 @@ impl super::Store {
8191
&self,
8292
mut progress: P,
8393
should_interrupt: &AtomicBool,
84-
options: pack::index::verify::integrity::Options<F>,
94+
options: integrity::Options<F>,
8595
) -> Result<integrity::Outcome<P>, integrity::Error>
8696
where
8797
P: Progress,

Diff for: git-odb/src/store_impls/loose/verify.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
use crate::loose::Store;
2-
use crate::Write;
1+
use std::{
2+
sync::atomic::{AtomicBool, Ordering},
3+
time::Instant,
4+
};
5+
36
use git_features::progress::Progress;
4-
use std::sync::atomic::{AtomicBool, Ordering};
7+
8+
use crate::{loose::Store, Write};
59

610
///
711
pub mod integrity {
@@ -47,6 +51,7 @@ impl Store {
4751
let sink = crate::sink(self.object_hash);
4852

4953
let mut num_objects = 0;
54+
let start = Instant::now();
5055
let mut progress = progress.add_child("validating");
5156
progress.init(None, git_features::progress::count("objects"));
5257
for id in self.iter().filter_map(Result::ok) {
@@ -74,6 +79,7 @@ impl Store {
7479
return Err(integrity::Error::Interrupted);
7580
}
7681
}
82+
progress.show_throughput(start);
7783

7884
Ok(integrity::Statistics { num_objects })
7985
}

Diff for: git-odb/tests/odb/store/dynamic.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -569,10 +569,12 @@ fn auto_refresh_with_and_without_id_stability() -> crate::Result {
569569
}
570570

571571
mod verify {
572-
use crate::store::dynamic::db;
572+
use std::sync::atomic::AtomicBool;
573+
573574
use git_features::progress;
574575
use git_testtools::fixture_path;
575-
use std::sync::atomic::AtomicBool;
576+
577+
use crate::store::dynamic::db;
576578

577579
#[test]
578580
fn integrity() {

Diff for: git-odb/tests/odb/store/loose.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use git_actor::{Sign, Time};
2-
use git_object::bstr::ByteSlice;
31
use std::sync::atomic::AtomicBool;
42

3+
use git_actor::{Sign, Time};
54
use git_features::progress;
5+
use git_object::bstr::ByteSlice;
66
use git_odb::loose::Store;
77
use pretty_assertions::assert_eq;
88

@@ -77,9 +77,7 @@ mod locate {
7777

7878
use crate::{
7979
hex_to_id,
80-
store::loose::{
81-
signature, {ldb, locate_oid},
82-
},
80+
store::loose::{ldb, locate_oid, signature},
8381
};
8482

8583
fn locate<'a>(hex: &str, buf: &'a mut Vec<u8>) -> git_object::Data<'a> {

Diff for: git-pack/src/index/traverse/with_lookup.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
use std::sync::atomic::{AtomicBool, Ordering};
2+
13
use git_features::{
24
parallel::{self, in_parallel_if},
35
progress::{self, unit, Progress},
46
};
5-
use std::sync::atomic::{AtomicBool, Ordering};
67

78
use super::{Error, Reducer};
89
use crate::{data, index, index::util};

Diff for: git-pack/src/multi_index/chunk.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,7 @@ pub mod lookup {
176176

177177
/// Information about the offsets table.
178178
pub mod offsets {
179-
use std::convert::TryInto;
180-
use std::ops::Range;
179+
use std::{convert::TryInto, ops::Range};
181180

182181
use byteorder::{BigEndian, WriteBytesExt};
183182

Diff for: git-pack/src/multi_index/verify.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
use std::time::Instant;
2-
use std::{cmp::Ordering, sync::atomic::AtomicBool};
1+
use std::{cmp::Ordering, sync::atomic::AtomicBool, time::Instant};
32

4-
use crate::index;
53
use git_features::progress::Progress;
64

7-
use crate::multi_index::File;
5+
use crate::{index, multi_index::File};
86

97
///
108
pub mod integrity {

Diff for: git-pack/src/multi_index/write.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
use std::sync::atomic::Ordering;
21
use std::{
32
convert::TryInto,
43
path::PathBuf,
5-
sync::atomic::AtomicBool,
4+
sync::atomic::{AtomicBool, Ordering},
65
time::{Instant, SystemTime},
76
};
87

Diff for: gitoxide-core/src/pack/multi_index.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
use git_repository::Progress;
2-
use std::io::BufWriter;
3-
use std::path::PathBuf;
4-
use std::sync::atomic::AtomicBool;
1+
use std::{io::BufWriter, path::PathBuf, sync::atomic::AtomicBool};
52

63
use git_repository as git;
4+
use git_repository::Progress;
75

86
pub const PROGRESS_RANGE: std::ops::RangeInclusive<u8> = 1..=3;
97

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

+27
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,30 @@ pub fn init(directory: Option<PathBuf>) -> Result<git_repository::Path> {
66
git_repository::path::create::into(directory.unwrap_or_default(), git_repository::Kind::WorkTree)
77
.with_context(|| "Repository initialization failed")
88
}
9+
10+
pub mod verify {
11+
use std::{path::PathBuf, sync::atomic::AtomicBool};
12+
13+
use git_repository::Progress;
14+
15+
use crate::OutputFormat;
16+
17+
pub const PROGRESS_RANGE: std::ops::RangeInclusive<u8> = 1..=4;
18+
19+
pub fn integrity(
20+
repo: PathBuf,
21+
_format: OutputFormat,
22+
_out: impl std::io::Write,
23+
progress: impl Progress,
24+
should_interrupt: &AtomicBool,
25+
) -> anyhow::Result<()> {
26+
let repo = git_repository::open(repo)?;
27+
// TODO: a way to get the pack cache from a handle
28+
repo.objects.verify_integrity(
29+
progress,
30+
should_interrupt,
31+
git_repository::odb::pack::index::verify::integrity::Options::default(),
32+
)?;
33+
Ok(())
34+
}
35+
}

Diff for: src/plumbing/main.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use gitoxide_core::pack::verify;
1515
#[cfg(any(feature = "gitoxide-core-async-client", feature = "gitoxide-core-blocking-client"))]
1616
use crate::plumbing::options::remote;
1717
use crate::{
18-
plumbing::options::{commitgraph, pack, Args, Subcommands},
18+
plumbing::options::{commitgraph, pack, repo, Args, Subcommands},
1919
shared::pretty::prepare_and_run,
2020
};
2121

@@ -73,6 +73,18 @@ pub fn main() -> Result<()> {
7373
})?;
7474

7575
match cmd {
76+
Subcommands::Repository(subcommands) => match subcommands {
77+
repo::Subcommands::Verify { repository } => prepare_and_run(
78+
"repository-verify",
79+
verbose,
80+
progress,
81+
progress_keep_open,
82+
core::repository::verify::PROGRESS_RANGE,
83+
move |progress, out, _err| {
84+
core::repository::verify::integrity(repository, format, out, progress, &should_interrupt)
85+
},
86+
),
87+
},
7688
Subcommands::Pack(subcommands) => match subcommands {
7789
pack::Subcommands::Create {
7890
repository,

Diff for: src/plumbing/options.rs

+30-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use gitoxide_core as core;
33

44
#[derive(Debug, clap::Parser)]
55
#[clap(name = "gix-plumbing", about = "The git underworld", version = clap::crate_version!())]
6-
#[clap(setting = AppSettings::SubcommandRequired)]
6+
#[clap(setting = AppSettings::SubcommandRequiredElseHelp)]
77
pub struct Args {
88
#[clap(long, short = 't')]
99
/// The amount of threads to use for some operations.
@@ -56,14 +56,17 @@ pub enum Subcommands {
5656
/// Subcommands for interacting with commit-graphs
5757
#[clap(subcommand)]
5858
CommitGraph(commitgraph::Subcommands),
59+
/// Subcommands for interacting with entire git repositories
60+
#[clap(subcommand)]
61+
Repository(repo::Subcommands),
5962
}
6063

6164
///
6265
pub mod pack {
66+
use std::{ffi::OsString, path::PathBuf};
67+
6368
use clap::AppSettings;
6469
use gitoxide_core as core;
65-
use std::ffi::OsString;
66-
use std::path::PathBuf;
6770

6871
#[derive(Debug, clap::Parser)]
6972
pub enum Subcommands {
@@ -243,9 +246,10 @@ pub mod pack {
243246

244247
///
245248
pub mod multi_index {
246-
use clap::AppSettings;
247249
use std::path::PathBuf;
248250

251+
use clap::AppSettings;
252+
249253
#[derive(Debug, clap::Parser)]
250254
pub enum Subcommands {
251255
/// Verify a multi-index quickly without inspecting objects themselves
@@ -272,9 +276,10 @@ pub mod pack {
272276

273277
///
274278
pub mod index {
279+
use std::path::PathBuf;
280+
275281
use clap::AppSettings;
276282
use gitoxide_core as core;
277-
use std::path::PathBuf;
278283

279284
#[derive(Debug, clap::Parser)]
280285
pub enum Subcommands {
@@ -314,10 +319,29 @@ pub mod pack {
314319
}
315320

316321
///
317-
pub mod commitgraph {
322+
pub mod repo {
323+
use std::path::PathBuf;
324+
318325
use clap::AppSettings;
326+
327+
#[derive(Debug, clap::Parser)]
328+
#[clap(alias = "repo")]
329+
pub enum Subcommands {
330+
/// Verify the integrity of the entire repository
331+
#[clap(setting = AppSettings::DisableVersionFlag)]
332+
Verify {
333+
#[clap(short = 'r', long, default_value = ".")]
334+
repository: PathBuf,
335+
},
336+
}
337+
}
338+
339+
///
340+
pub mod commitgraph {
319341
use std::path::PathBuf;
320342

343+
use clap::AppSettings;
344+
321345
#[derive(Debug, clap::Parser)]
322346
pub enum Subcommands {
323347
/// Verify the integrity of a commit graph

Diff for: tests/journey/gix.sh

+16
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,22 @@ title "git-tempfile crate"
3939
)
4040
)
4141

42+
title "gix repository"
43+
(when "running 'repository'"
44+
snapshot="$snapshot/repository"
45+
(small-repo-in-sandbox
46+
(with "the 'verify' sub-command"
47+
snapshot="$snapshot/verify"
48+
(with 'human output format'
49+
it "generates correct output" && {
50+
WITH_SNAPSHOT="$snapshot/success-format-human" \
51+
expect_run $SUCCESSFULLY "$exe_plumbing" --format human repo verify
52+
}
53+
)
54+
)
55+
)
56+
)
57+
4258
title "gix pack"
4359
(when "running 'pack'"
4460
snapshot="$snapshot/pack"

Diff for: tests/snapshots/plumbing/repository/verify/success-format-human

Whitespace-only changes.

0 commit comments

Comments
 (0)