Skip to content

Commit

Permalink
Very rough version of repository verification (#287)
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Jan 2, 2022
1 parent 53d835a commit 80a4a7a
Show file tree
Hide file tree
Showing 15 changed files with 128 additions and 39 deletions.
3 changes: 1 addition & 2 deletions git-hash/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@

mod borrowed;

use std::convert::TryFrom;
use std::str::FromStr;
use std::{convert::TryFrom, str::FromStr};

pub use borrowed::oid;

Expand Down
24 changes: 17 additions & 7 deletions git-odb/src/store_impls/dynamic/verify.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
use crate::pack;
use crate::store::verify::integrity::{IndexStatistics, SingleOrMultiStatistics};
use crate::types::IndexAndPacks;
use std::{
ops::Deref,
sync::atomic::{AtomicBool, Ordering},
};

use git_features::progress::Progress;
use std::ops::Deref;
use std::sync::atomic::{AtomicBool, Ordering};

use crate::{
pack,
store::verify::integrity::{IndexStatistics, SingleOrMultiStatistics},
types::IndexAndPacks,
};

///
pub mod integrity {
use crate::pack;
use std::path::PathBuf;

use crate::pack;

/// Options for use in [`Store::verify_integrity()`][crate::Store::verify_integrity()].
pub type Options<F> = pack::index::verify::integrity::Options<F>;

/// Returned by [`Store::verify_integrity()`][crate::Store::verify_integrity()].
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
Expand Down Expand Up @@ -81,7 +91,7 @@ impl super::Store {
&self,
mut progress: P,
should_interrupt: &AtomicBool,
options: pack::index::verify::integrity::Options<F>,
options: integrity::Options<F>,
) -> Result<integrity::Outcome<P>, integrity::Error>
where
P: Progress,
Expand Down
12 changes: 9 additions & 3 deletions git-odb/src/store_impls/loose/verify.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
use crate::loose::Store;
use crate::Write;
use std::{
sync::atomic::{AtomicBool, Ordering},
time::Instant,
};

use git_features::progress::Progress;
use std::sync::atomic::{AtomicBool, Ordering};

use crate::{loose::Store, Write};

///
pub mod integrity {
Expand Down Expand Up @@ -47,6 +51,7 @@ impl Store {
let sink = crate::sink(self.object_hash);

let mut num_objects = 0;
let start = Instant::now();
let mut progress = progress.add_child("validating");
progress.init(None, git_features::progress::count("objects"));
for id in self.iter().filter_map(Result::ok) {
Expand Down Expand Up @@ -74,6 +79,7 @@ impl Store {
return Err(integrity::Error::Interrupted);
}
}
progress.show_throughput(start);

Ok(integrity::Statistics { num_objects })
}
Expand Down
6 changes: 4 additions & 2 deletions git-odb/tests/odb/store/dynamic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,10 +569,12 @@ fn auto_refresh_with_and_without_id_stability() -> crate::Result {
}

mod verify {
use crate::store::dynamic::db;
use std::sync::atomic::AtomicBool;

use git_features::progress;
use git_testtools::fixture_path;
use std::sync::atomic::AtomicBool;

use crate::store::dynamic::db;

#[test]
fn integrity() {
Expand Down
8 changes: 3 additions & 5 deletions git-odb/tests/odb/store/loose.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use git_actor::{Sign, Time};
use git_object::bstr::ByteSlice;
use std::sync::atomic::AtomicBool;

use git_actor::{Sign, Time};
use git_features::progress;
use git_object::bstr::ByteSlice;
use git_odb::loose::Store;
use pretty_assertions::assert_eq;

Expand Down Expand Up @@ -77,9 +77,7 @@ mod locate {

use crate::{
hex_to_id,
store::loose::{
signature, {ldb, locate_oid},
},
store::loose::{ldb, locate_oid, signature},
};

fn locate<'a>(hex: &str, buf: &'a mut Vec<u8>) -> git_object::Data<'a> {
Expand Down
3 changes: 2 additions & 1 deletion git-pack/src/index/traverse/with_lookup.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::sync::atomic::{AtomicBool, Ordering};

use git_features::{
parallel::{self, in_parallel_if},
progress::{self, unit, Progress},
};
use std::sync::atomic::{AtomicBool, Ordering};

use super::{Error, Reducer};
use crate::{data, index, index::util};
Expand Down
3 changes: 1 addition & 2 deletions git-pack/src/multi_index/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,7 @@ pub mod lookup {

/// Information about the offsets table.
pub mod offsets {
use std::convert::TryInto;
use std::ops::Range;
use std::{convert::TryInto, ops::Range};

use byteorder::{BigEndian, WriteBytesExt};

Expand Down
6 changes: 2 additions & 4 deletions git-pack/src/multi_index/verify.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
use std::time::Instant;
use std::{cmp::Ordering, sync::atomic::AtomicBool};
use std::{cmp::Ordering, sync::atomic::AtomicBool, time::Instant};

use crate::index;
use git_features::progress::Progress;

use crate::multi_index::File;
use crate::{index, multi_index::File};

///
pub mod integrity {
Expand Down
3 changes: 1 addition & 2 deletions git-pack/src/multi_index/write.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use std::sync::atomic::Ordering;
use std::{
convert::TryInto,
path::PathBuf,
sync::atomic::AtomicBool,
sync::atomic::{AtomicBool, Ordering},
time::{Instant, SystemTime},
};

Expand Down
6 changes: 2 additions & 4 deletions gitoxide-core/src/pack/multi_index.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use git_repository::Progress;
use std::io::BufWriter;
use std::path::PathBuf;
use std::sync::atomic::AtomicBool;
use std::{io::BufWriter, path::PathBuf, sync::atomic::AtomicBool};

use git_repository as git;
use git_repository::Progress;

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

Expand Down
27 changes: 27 additions & 0 deletions gitoxide-core/src/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,30 @@ pub fn init(directory: Option<PathBuf>) -> Result<git_repository::Path> {
git_repository::path::create::into(directory.unwrap_or_default(), git_repository::Kind::WorkTree)
.with_context(|| "Repository initialization failed")
}

pub mod verify {
use std::{path::PathBuf, sync::atomic::AtomicBool};

use git_repository::Progress;

use crate::OutputFormat;

pub const PROGRESS_RANGE: std::ops::RangeInclusive<u8> = 1..=4;

pub fn integrity(
repo: PathBuf,
_format: OutputFormat,
_out: impl std::io::Write,
progress: impl Progress,
should_interrupt: &AtomicBool,
) -> anyhow::Result<()> {
let repo = git_repository::open(repo)?;
// TODO: a way to get the pack cache from a handle
repo.objects.verify_integrity(
progress,
should_interrupt,
git_repository::odb::pack::index::verify::integrity::Options::default(),
)?;
Ok(())
}
}
14 changes: 13 additions & 1 deletion src/plumbing/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use gitoxide_core::pack::verify;
#[cfg(any(feature = "gitoxide-core-async-client", feature = "gitoxide-core-blocking-client"))]
use crate::plumbing::options::remote;
use crate::{
plumbing::options::{commitgraph, pack, Args, Subcommands},
plumbing::options::{commitgraph, pack, repo, Args, Subcommands},
shared::pretty::prepare_and_run,
};

Expand Down Expand Up @@ -73,6 +73,18 @@ pub fn main() -> Result<()> {
})?;

match cmd {
Subcommands::Repository(subcommands) => match subcommands {
repo::Subcommands::Verify { repository } => prepare_and_run(
"repository-verify",
verbose,
progress,
progress_keep_open,
core::repository::verify::PROGRESS_RANGE,
move |progress, out, _err| {
core::repository::verify::integrity(repository, format, out, progress, &should_interrupt)
},
),
},
Subcommands::Pack(subcommands) => match subcommands {
pack::Subcommands::Create {
repository,
Expand Down
36 changes: 30 additions & 6 deletions src/plumbing/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use gitoxide_core as core;

#[derive(Debug, clap::Parser)]
#[clap(name = "gix-plumbing", about = "The git underworld", version = clap::crate_version!())]
#[clap(setting = AppSettings::SubcommandRequired)]
#[clap(setting = AppSettings::SubcommandRequiredElseHelp)]
pub struct Args {
#[clap(long, short = 't')]
/// The amount of threads to use for some operations.
Expand Down Expand Up @@ -56,14 +56,17 @@ pub enum Subcommands {
/// Subcommands for interacting with commit-graphs
#[clap(subcommand)]
CommitGraph(commitgraph::Subcommands),
/// Subcommands for interacting with entire git repositories
#[clap(subcommand)]
Repository(repo::Subcommands),
}

///
pub mod pack {
use std::{ffi::OsString, path::PathBuf};

use clap::AppSettings;
use gitoxide_core as core;
use std::ffi::OsString;
use std::path::PathBuf;

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

///
pub mod multi_index {
use clap::AppSettings;
use std::path::PathBuf;

use clap::AppSettings;

#[derive(Debug, clap::Parser)]
pub enum Subcommands {
/// Verify a multi-index quickly without inspecting objects themselves
Expand All @@ -272,9 +276,10 @@ pub mod pack {

///
pub mod index {
use std::path::PathBuf;

use clap::AppSettings;
use gitoxide_core as core;
use std::path::PathBuf;

#[derive(Debug, clap::Parser)]
pub enum Subcommands {
Expand Down Expand Up @@ -314,10 +319,29 @@ pub mod pack {
}

///
pub mod commitgraph {
pub mod repo {
use std::path::PathBuf;

use clap::AppSettings;

#[derive(Debug, clap::Parser)]
#[clap(alias = "repo")]
pub enum Subcommands {
/// Verify the integrity of the entire repository
#[clap(setting = AppSettings::DisableVersionFlag)]
Verify {
#[clap(short = 'r', long, default_value = ".")]
repository: PathBuf,
},
}
}

///
pub mod commitgraph {
use std::path::PathBuf;

use clap::AppSettings;

#[derive(Debug, clap::Parser)]
pub enum Subcommands {
/// Verify the integrity of a commit graph
Expand Down
16 changes: 16 additions & 0 deletions tests/journey/gix.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,22 @@ title "git-tempfile crate"
)
)

title "gix repository"
(when "running 'repository'"
snapshot="$snapshot/repository"
(small-repo-in-sandbox
(with "the 'verify' sub-command"
snapshot="$snapshot/verify"
(with 'human output format'
it "generates correct output" && {
WITH_SNAPSHOT="$snapshot/success-format-human" \
expect_run $SUCCESSFULLY "$exe_plumbing" --format human repo verify
}
)
)
)
)

title "gix pack"
(when "running 'pack'"
snapshot="$snapshot/pack"
Expand Down
Empty file.

0 comments on commit 80a4a7a

Please sign in to comment.