From 1805d64b9222d6a05a8718f04b29b789c1f42fea Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 27 Jul 2020 15:28:57 +0800 Subject: [PATCH] Get all pieces ready for action --- Cargo.lock | 1 + gitoxide-core/Cargo.toml | 1 + gitoxide-core/src/pack/explode.rs | 52 +++++++++++++++++++++++++++++-- src/plumbing/lean.rs | 12 +++++-- src/plumbing/pretty.rs | 13 ++++++-- 5 files changed, 70 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f7a2e7df500..fa72d822d3d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -743,6 +743,7 @@ dependencies = [ "git-object", "git-odb", "git-repository", + "quick-error 1.2.3 (git+https://github.com/tailhook/quick-error?rev=aad5701556438218339fba452451ae63a47c31c2)", "serde_json", ] diff --git a/gitoxide-core/Cargo.toml b/gitoxide-core/Cargo.toml index c8166074f5b..f02af726f22 100644 --- a/gitoxide-core/Cargo.toml +++ b/gitoxide-core/Cargo.toml @@ -23,5 +23,6 @@ git-object = { version = "^0.2.0", path = "../git-object" } git-odb = { version = "0.1.0", path = "../git-odb" } git-features = { version = "^0.2.0", path = "../git-features" } anyhow = "1.0.31" +quick-error = { version = "1.2.3", git = "https://github.com/tailhook/quick-error", rev = "aad5701556438218339fba452451ae63a47c31c2" } bytesize = "1.0.1" serde_json = { version = "1.0.56", optional = true } diff --git a/gitoxide-core/src/pack/explode.rs b/gitoxide-core/src/pack/explode.rs index 4d10e531e36..f73480ebdd5 100644 --- a/gitoxide-core/src/pack/explode.rs +++ b/gitoxide-core/src/pack/explode.rs @@ -1,6 +1,8 @@ use anyhow::{Context, Result}; use git_features::progress::Progress; -use git_odb::pack; +use git_object::{owned, HashKind}; +use git_odb::{loose, pack}; +use std::io::Read; use std::path::Path; #[derive(PartialEq, Debug)] @@ -52,8 +54,50 @@ impl From for pack::index::traverse::SafetyCheck { } } +use quick_error::quick_error; + +quick_error! { + #[derive(Debug)] + enum Error { + Io(err: std::io::Error) { + source(err) + from() + } + Odb(err: loose::db::write::Error) { + source(err) + from() + } + } +} + +struct OutputWriter(Option); + +impl git_odb::Write for OutputWriter { + type Error = Error; + + fn write_stream( + &self, + kind: git_object::Kind, + size: u64, + from: impl Read, + hash: HashKind, + ) -> Result { + match self.0.as_ref() { + Some(db) => db.write_stream(kind, size, from, hash).map_err(Into::into), + None => git_odb::sink().write_stream(kind, size, from, hash).map_err(Into::into), + } + } + fn write_buf(&self, kind: git_object::Kind, from: &[u8], hash: HashKind) -> Result { + match self.0.as_ref() { + Some(db) => db.write_buf(kind, from, hash).map_err(Into::into), + None => git_odb::sink().write_buf(kind, from, hash).map_err(Into::into), + } + } +} + pub fn pack_or_pack_index

( - path: impl AsRef, + pack_path: impl AsRef, + object_path: Option>, _check: SafetyCheck, _progress: Option

, _delete_pack: bool, @@ -61,12 +105,14 @@ pub fn pack_or_pack_index

( where P: Progress, { - let path = path.as_ref(); + let path = pack_path.as_ref(); let _bundle = pack::Bundle::at(path).with_context(|| { format!( "Could not find .idx or .pack file from given file at '{}'", path.display() ) })?; + + let _out = OutputWriter(object_path.map(|path| loose::Db::at(path.as_ref()))); Ok(()) } diff --git a/src/plumbing/lean.rs b/src/plumbing/lean.rs index f3a0422305c..f772ca0a0aa 100644 --- a/src/plumbing/lean.rs +++ b/src/plumbing/lean.rs @@ -54,7 +54,11 @@ mod options { /// the '.pack' or '.idx' file to explode into loose objects #[argh(positional)] - pub path: PathBuf, + pub pack_path: PathBuf, + + /// the path into which all objects should be written. Commonly '.git/objects' + #[argh(positional)] + pub object_path: Option, } /// Verify a pack @@ -131,14 +135,16 @@ pub fn main() -> Result<()> { let thread_limit = cli.threads; match cli.subcommand { SubCommands::PackExplode(PackExplode { - path, + pack_path, + object_path, verbose, check, delete_pack, }) => { let (_handle, progress) = prepare(verbose, "pack-explode"); core::pack::explode::pack_or_pack_index( - path, + pack_path, + object_path, check.unwrap_or(core::pack::explode::SafetyCheck::All), progress, delete_pack, diff --git a/src/plumbing/pretty.rs b/src/plumbing/pretty.rs index 32001109949..033c064b807 100644 --- a/src/plumbing/pretty.rs +++ b/src/plumbing/pretty.rs @@ -59,7 +59,11 @@ mod options { /// The '.pack' or '.idx' file to explode into loose objects #[structopt(parse(from_os_str))] - path: PathBuf, + pack_path: PathBuf, + + /// The path into which all objects should be written. Commonly '.git/objects' + #[structopt(parse(from_os_str))] + object_path: Option, }, /// Verify the integrity of a pack or index file #[structopt(setting = AppSettings::ColoredHelp)] @@ -221,13 +225,16 @@ pub fn main() -> Result<()> { progress, progress_keep_open, delete_pack, - path, + pack_path, + object_path, } => prepare_and_run( "pack-explode", verbose, progress, progress_keep_open, - move |progress, _out, _err| core::pack::explode::pack_or_pack_index(path, check, progress, delete_pack), + move |progress, _out, _err| { + core::pack::explode::pack_or_pack_index(pack_path, object_path, check, progress, delete_pack) + }, ), Subcommands::PackVerify { path,