Skip to content

Commit

Permalink
Basic multi-pack index creation (#279)
Browse files Browse the repository at this point in the history
Could imagine providing statistics as part of the creation result.
  • Loading branch information
Byron committed Jan 1, 2022
1 parent c4c5678 commit 89428b2
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 8 deletions.
12 changes: 12 additions & 0 deletions git-hash/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
mod borrowed;

use std::convert::TryFrom;
use std::str::FromStr;

pub use borrowed::oid;

Expand Down Expand Up @@ -85,6 +86,17 @@ impl TryFrom<u8> for Kind {
}
}

impl FromStr for Kind {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"sha1" | "SHA1" => Kind::Sha1,
other => return Err(other.into()),
})
}
}

impl Kind {
/// Returns the shortest hash we support
#[inline]
Expand Down
3 changes: 2 additions & 1 deletion gitoxide-core/src/pack/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ pub struct Context<'a, W: io::Write> {
pub format: OutputFormat,
pub should_interrupt: &'a AtomicBool,
pub out: W,
pub object_hash: git_repository::hash::Kind,
}

pub fn stream_len(mut s: impl io::Seek) -> io::Result<u64> {
Expand Down Expand Up @@ -85,7 +86,7 @@ pub fn from_pack(
thread_limit: ctx.thread_limit,
iteration_mode: ctx.iteration_mode.into(),
index_kind: pack::index::Version::default(),
object_hash: git_repository::hash::Kind::Sha1, // TODO: make this configurable via CLI, context
object_hash: ctx.object_hash,
};
let out = ctx.out;
let format = ctx.format;
Expand Down
1 change: 1 addition & 0 deletions gitoxide-core/src/pack/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod explode;
pub mod index;
pub mod multi_index;
pub mod verify;

#[cfg(any(feature = "async-client", feature = "blocking-client"))]
Expand Down
31 changes: 31 additions & 0 deletions gitoxide-core/src/pack/multi_index.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use git_repository::Progress;
use std::io::BufWriter;
use std::path::PathBuf;
use std::sync::atomic::AtomicBool;

use git_repository as git;

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

pub fn create(
index_paths: Vec<PathBuf>,
output_path: PathBuf,
progress: impl Progress,
should_interrupt: &AtomicBool,
object_hash: git::hash::Kind,
) -> anyhow::Result<()> {
let mut out = BufWriter::new(git::lock::File::acquire_to_update_resource(
output_path,
git::lock::acquire::Fail::Immediately,
None,
)?);
git::odb::pack::multi_index::File::write_from_index_paths(
index_paths,
&mut out,
progress,
should_interrupt,
git::odb::pack::multi_index::write::Options { object_hash },
)?;
out.into_inner()?.commit()?;
Ok(())
}
27 changes: 25 additions & 2 deletions src/plumbing/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub fn main() -> Result<()> {
let verbose = args.verbose;
let format = args.format;
let cmd = args.cmd;
let object_hash = args.object_hash;

let progress;
let progress_keep_open;
Expand Down Expand Up @@ -241,13 +242,34 @@ pub fn main() -> Result<()> {
},
)
.map(|_| ()),
pack::Subcommands::MultiIndex(subcommands) => match subcommands {
pack::multi_index::Subcommands::Create {
output_path,
index_paths,
} => prepare_and_run(
"pack-multi-index-create",
verbose,
progress,
progress_keep_open,
core::pack::multi_index::PROGRESS_RANGE,
move |progress, _out, _err| {
core::pack::multi_index::create(
index_paths,
output_path,
progress,
&git_repository::interrupt::IS_INTERRUPTED,
object_hash,
)
},
),
},
pack::Subcommands::Index(subcommands) => match subcommands {
pack::index::Subcommands::Create {
iteration_mode,
pack_path,
directory,
} => prepare_and_run(
"pack-index-from-data",
"pack-index-create",
verbose,
progress,
progress_keep_open,
Expand All @@ -273,6 +295,7 @@ pub fn main() -> Result<()> {
iteration_mode,
format,
out,
object_hash,
should_interrupt: &git_repository::interrupt::IS_INTERRUPTED,
},
)
Expand Down Expand Up @@ -321,7 +344,7 @@ pub fn main() -> Result<()> {
},
Subcommands::Commitgraph(subcommands) => match subcommands {
commitgraph::Subcommands::Verify { path, statistics } => prepare_and_run(
"commit-graph-verify",
"commitgraph-verify",
verbose,
progress,
progress_keep_open,
Expand Down
36 changes: 33 additions & 3 deletions src/plumbing/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ pub struct Args {
)]
pub format: core::OutputFormat,

/// The object format to assume when reading files that don't inherently know about it, or when writing files.
#[clap(long, default_value = "sha1", possible_values(&["sha1"]))]
pub object_hash: git_repository::hash::Kind,

#[clap(subcommand)]
pub cmd: Subcommands,
}
Expand Down Expand Up @@ -63,6 +67,12 @@ pub mod pack {

#[derive(Debug, clap::Parser)]
pub enum Subcommands {
/// Subcommands for interacting with pack indices (.idx)
#[clap(subcommand)]
Index(index::Subcommands),
/// Subcommands for interacting with multi-pack indices (named "multi-pack-index")
#[clap(subcommand)]
MultiIndex(multi_index::Subcommands),
/// Create a new pack with a set of objects.
#[clap(setting = AppSettings::DisableVersionFlag)]
Create {
Expand Down Expand Up @@ -153,9 +163,6 @@ pub mod pack {
/// If unset, they will be discarded.
directory: Option<PathBuf>,
},
/// Subcommands for interacting with pack indices (.idx)
#[clap(subcommand)]
Index(index::Subcommands),
/// Dissolve a pack into its loose objects.
///
/// Note that this effectively removes delta compression for an average compression of 2x, creating one file per object in the process.
Expand Down Expand Up @@ -234,6 +241,29 @@ pub mod pack {
},
}

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

#[derive(Debug, clap::Parser)]
pub enum Subcommands {
/// create a multi-pack index from one or more pack index files
#[clap(setting = AppSettings::DisableVersionFlag)]
Create {
/// The path to which the multi-index file should be written, overwriting any possibly existing file.
///
/// Note for the multi-index to be useful, it should be side-by-side with the supplied `.idx` files.
#[clap(long, short = 'o')]
output_path: PathBuf,

/// Paths to the pack index files to read (with .idx extension).
#[clap(required = true)]
index_paths: Vec<PathBuf>,
},
}
}

///
pub mod index {
use clap::AppSettings;
Expand Down
15 changes: 13 additions & 2 deletions tests/journey/gix.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ title "git-tempfile crate"
title "gix pack"
(when "running 'pack'"
snapshot="$snapshot/pack"

title "gix pack receive"
(with "the 'receive' sub-command"
snapshot="$snapshot/receive"
Expand Down Expand Up @@ -265,7 +265,18 @@ title "gix pack"

title "gix pack multi-index"
(with "the 'multi-index' sub-command"

snapshot="$snapshot/multi-index"
title "gix pack multi-index create"
(with "the 'create' sub-command"
snapshot="$snapshot/create"
(with 'multiple pack indices'
(sandbox
it "creates a multi-index successfully" && {
expect_run $SUCCESSFULLY "$exe_plumbing" pack multi-index create $fixtures/packs/pack-*.idx -o multi-pack-index
}
)
)
)
)

title "gix pack explode"
Expand Down

0 comments on commit 89428b2

Please sign in to comment.