diff --git a/git-odb/src/loose/mod.rs b/git-odb/src/loose/mod.rs index c9f9725f339..b39168af3db 100644 --- a/git-odb/src/loose/mod.rs +++ b/git-odb/src/loose/mod.rs @@ -2,9 +2,10 @@ const HEADER_READ_COMPRESSED_BYTES: usize = 256; const HEADER_READ_UNCOMPRESSED_BYTES: usize = 512; pub(crate) mod db; -mod object; + +pub mod object; +pub use object::*; pub mod stream; -pub use db::{Db, Error as DbError}; -pub use object::*; +pub use db::{Db, Error}; diff --git a/git-odb/src/loose/object.rs b/git-odb/src/loose/object.rs index acc7317695a..5e3b8ac24f9 100644 --- a/git-odb/src/loose/object.rs +++ b/git-odb/src/loose/object.rs @@ -1,34 +1,7 @@ -use crate::{ - loose::stream::ObjectReader, - loose::{HEADER_READ_COMPRESSED_BYTES, HEADER_READ_UNCOMPRESSED_BYTES}, - zlib, -}; +use crate::loose::{HEADER_READ_COMPRESSED_BYTES, HEADER_READ_UNCOMPRESSED_BYTES}; use git_object as object; -use miniz_oxide::inflate::decompress_to_vec_zlib; -use object::borrowed; -use quick_error::quick_error; use smallvec::SmallVec; -use std::{io::Read, path::PathBuf}; - -quick_error! { - #[derive(Debug)] - pub enum Error { - Decompress(err: zlib::Error) { - display("decompression of object data failed") - from() - cause(err) - } - ParseTag(err: borrowed::Error) { - display("Could not parse tag object") - from() - cause(err) - } - Io(err: std::io::Error, action: &'static str, path: PathBuf) { - display("Could not {} data at '{}'", action, path.display()) - cause(err) - } - } -} +use std::path::PathBuf; #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] pub struct Object { @@ -41,59 +14,86 @@ pub struct Object { pub(crate) decompression_complete: bool, } -impl Object { - // Note: Blobs are loaded or mapped into memory and are made available that way. - // Consider the streaming API if large Blobs are expected. - pub fn decode(&mut self) -> Result { - self.decompress_all()?; - let bytes = &self.decompressed_data[self.header_size..]; - Ok(match self.kind { - object::Kind::Tag => borrowed::Object::Tag(borrowed::Tag::from_bytes(bytes)?), - object::Kind::Tree => borrowed::Object::Tree(borrowed::Tree::from_bytes(bytes)?), - object::Kind::Commit => borrowed::Object::Commit(borrowed::Commit::from_bytes(bytes)?), - object::Kind::Blob => borrowed::Object::Blob(borrowed::Blob { data: bytes }), - }) - } +pub mod decode { + use crate::{loose, loose::stream::Reader, zlib}; + use git_object as object; + use miniz_oxide::inflate::decompress_to_vec_zlib; + use object::borrowed; + use quick_error::quick_error; + use smallvec::SmallVec; + use std::{io::Read, path::PathBuf}; - pub fn stream(&self) -> Result { - match &self.path { - Some(path) => Ok(ObjectReader::from_read( - self.header_size, - std::fs::File::open(path).map_err(|e| Error::Io(e, "open", path.to_owned()))?, - )), - None => Ok(ObjectReader::from_data( - self.header_size, - &self.decompressed_data.as_slice(), - )), + quick_error! { + #[derive(Debug)] + pub enum Error { + Decompress(err: zlib::Error) { + display("decompression of object data failed") + from() + cause(err) + } + ParseTag(err: borrowed::Error) { + display("Could not parse tag object") + from() + cause(err) + } + Io(err: std::io::Error, action: &'static str, path: PathBuf) { + display("Could not {} data at '{}'", action, path.display()) + cause(err) + } } } - fn decompress_all(&mut self) -> Result<(), Error> { - if self.decompression_complete { - debug_assert!( - self.size + self.header_size == self.decompressed_data.len(), - "when decompression is done, we have stored everything in memory" - ); - return Ok(()); + impl loose::Object { + // Note: Blobs are loaded or mapped into memory and are made available that way. + // Consider the streaming API if large Blobs are expected. + pub fn decode(&mut self) -> Result { + self.decompress_all()?; + let bytes = &self.decompressed_data[self.header_size..]; + Ok(match self.kind { + object::Kind::Tag => borrowed::Object::Tag(borrowed::Tag::from_bytes(bytes)?), + object::Kind::Tree => borrowed::Object::Tree(borrowed::Tree::from_bytes(bytes)?), + object::Kind::Commit => borrowed::Object::Commit(borrowed::Commit::from_bytes(bytes)?), + object::Kind::Blob => borrowed::Object::Blob(borrowed::Blob { data: bytes }), + }) } - let total_size = self.header_size + self.size; - if let Some(path) = self.path.take() { - // NOTE: For now we just re-read everything from the beginning without seeking, as our buffer - // is small so the seek might be more expensive than just reading everything. - let mut file = std::fs::File::open(&path).map_err(|e| Error::Io(e, "open", path.clone()))?; - let file_size = file - .metadata() - .map_err(|e| Error::Io(e, "read metadata", path.clone()))? - .len() as usize; - let mut buf = Vec::with_capacity(file_size); - file.read_to_end(&mut buf).map_err(|e| Error::Io(e, "read", path))?; - self.compressed_data = SmallVec::from(buf); + + pub fn stream(&self) -> Result { + match &self.path { + Some(path) => Ok(Reader::from_read( + self.header_size, + std::fs::File::open(path).map_err(|e| Error::Io(e, "open", path.to_owned()))?, + )), + None => Ok(Reader::from_data(self.header_size, &self.decompressed_data.as_slice())), + } + } + + fn decompress_all(&mut self) -> Result<(), Error> { + if self.decompression_complete { + debug_assert!( + self.size + self.header_size == self.decompressed_data.len(), + "when decompression is done, we have stored everything in memory" + ); + return Ok(()); + } + let total_size = self.header_size + self.size; + if let Some(path) = self.path.take() { + // NOTE: For now we just re-read everything from the beginning without seeking, as our buffer + // is small so the seek might be more expensive than just reading everything. + let mut file = std::fs::File::open(&path).map_err(|e| Error::Io(e, "open", path.clone()))?; + let file_size = file + .metadata() + .map_err(|e| Error::Io(e, "read metadata", path.clone()))? + .len() as usize; + let mut buf = Vec::with_capacity(file_size); + file.read_to_end(&mut buf).map_err(|e| Error::Io(e, "read", path))?; + self.compressed_data = SmallVec::from(buf); + } + self.decompressed_data = SmallVec::from(decompress_to_vec_zlib(&self.compressed_data[..]).unwrap()); + self.decompressed_data.shrink_to_fit(); + assert!(self.decompressed_data.len() == total_size); + self.decompression_complete = true; + self.compressed_data = Default::default(); + Ok(()) } - self.decompressed_data = SmallVec::from(decompress_to_vec_zlib(&self.compressed_data[..]).unwrap()); - self.decompressed_data.shrink_to_fit(); - assert!(self.decompressed_data.len() == total_size); - self.decompression_complete = true; - self.compressed_data = Default::default(); - Ok(()) } } diff --git a/git-odb/src/loose/stream.rs b/git-odb/src/loose/stream.rs index 2a98df985c9..3802aafca6d 100644 --- a/git-odb/src/loose/stream.rs +++ b/git-odb/src/loose/stream.rs @@ -1,25 +1,25 @@ use crate::zlib::stream::InflateReader; use std::io::BufReader; -pub enum ObjectReader<'data> { +pub enum Reader<'data> { File(usize, InflateReader>), Buffer(&'data [u8]), } -impl<'data> ObjectReader<'data> { - pub fn from_read(header_size: usize, file: std::fs::File) -> ObjectReader<'data> { - ObjectReader::File(header_size, InflateReader::new(file)) +impl<'data> Reader<'data> { + pub fn from_read(header_size: usize, file: std::fs::File) -> Reader<'data> { + Reader::File(header_size, InflateReader::new(file)) } - pub fn from_data(header_size: usize, data: &'data [u8]) -> ObjectReader<'data> { - ObjectReader::Buffer(&data[header_size..]) + pub fn from_data(header_size: usize, data: &'data [u8]) -> Reader<'data> { + Reader::Buffer(&data[header_size..]) } } -impl<'data> std::io::Read for ObjectReader<'data> { +impl<'data> std::io::Read for Reader<'data> { fn read(&mut self, buf: &mut [u8]) -> std::io::Result { match self { - ObjectReader::Buffer(data) => data.read(buf), - ObjectReader::File(header_size_left, r) => { + Reader::Buffer(data) => data.read(buf), + Reader::File(header_size_left, r) => { if *header_size_left == 0 { r.read(buf) } else { diff --git a/git-odb/src/pack/bundle.rs b/git-odb/src/pack/bundle.rs index 977fd5340a7..9ad3e8610cc 100644 --- a/git-odb/src/pack/bundle.rs +++ b/git-odb/src/pack/bundle.rs @@ -11,7 +11,7 @@ quick_error! { #[derive(Debug)] pub enum Error { InvalidPath(path: PathBuf) { - display("An 'idx' extension is expected of an index data: '{}'", path.display()) + display("An 'idx' extension is expected of an index file: '{}'", path.display()) } Pack(err: pack::data::init::Error) { display("Could not instantiate pack") @@ -36,7 +36,7 @@ pub struct Bundle { } impl Bundle { - /// `path` is either a pack data or an index data + /// `path` is either a pack file or an index file pub fn at(path: impl AsRef) -> Result { Self::try_from(path.as_ref()) } diff --git a/git-odb/src/pack/data/decode.rs b/git-odb/src/pack/data/decode.rs index 5e1bdc50d7d..64fa7295faf 100644 --- a/git-odb/src/pack/data/decode.rs +++ b/git-odb/src/pack/data/decode.rs @@ -85,7 +85,7 @@ impl File { } /// Currently only done during pack verification - finding the right size is only possible by decompressing - /// the pack entry beforehand, or by using the (to be sorted) offsets stored in an index data. + /// the pack entry beforehand, or by using the (to be sorted) offsets stored in an index file. pub fn entry_crc32(&self, pack_offset: u64, size: usize) -> u32 { let pack_offset: usize = pack_offset.try_into().expect("pack_size fits into usize"); git_features::hash::crc32(&self.data[pack_offset..pack_offset + size]) diff --git a/git-odb/src/pack/data/init.rs b/git-odb/src/pack/data/init.rs index 443a215b51b..5f3360b7335 100644 --- a/git-odb/src/pack/data/init.rs +++ b/git-odb/src/pack/data/init.rs @@ -9,7 +9,7 @@ quick_error! { #[derive(Debug)] pub enum Error { Io(err: std::io::Error, path: std::path::PathBuf) { - display("Could not open pack data at '{}'", path.display()) + display("Could not open pack file at '{}'", path.display()) cause(err) } Corrupt(msg: String) { diff --git a/git-odb/src/pack/data/verify.rs b/git-odb/src/pack/data/verify.rs index e8fa0d191ac..b0cefc5136d 100644 --- a/git-odb/src/pack/data/verify.rs +++ b/git-odb/src/pack/data/verify.rs @@ -9,7 +9,7 @@ quick_error! { display("pack checksum mismatch: expected {}, got {}", expected, actual) } Io(err: std::io::Error) { - display("could not read pack data") + display("could not read pack file") from() cause(err) } diff --git a/git-odb/src/pack/index/init.rs b/git-odb/src/pack/index/init.rs index 17af9da454a..0c821df2318 100644 --- a/git-odb/src/pack/index/init.rs +++ b/git-odb/src/pack/index/init.rs @@ -9,7 +9,7 @@ quick_error! { #[derive(Debug)] pub enum Error { Io(err: std::io::Error, path: std::path::PathBuf) { - display("Could not open pack index data at '{}'", path.display()) + display("Could not open pack index file at '{}'", path.display()) cause(err) } Corrupt(msg: String) { diff --git a/git-odb/src/pack/index/verify.rs b/git-odb/src/pack/index/verify.rs index 90ea18bf5af..469d331a164 100644 --- a/git-odb/src/pack/index/verify.rs +++ b/git-odb/src/pack/index/verify.rs @@ -16,7 +16,7 @@ quick_error! { display("index checksum mismatch: expected {}, got {}", expected, actual) } PackChecksum(err: pack::data::verify::Error) { - display("The pack of this index data failed to verify its checksums") + display("The pack of this index file failed to verify its checksums") from() cause(err) } @@ -25,13 +25,13 @@ quick_error! { cause(err) } PackMismatch { expected: git_object::Id, actual: git_object::Id } { - display("The packfiles checksum didn't match the index data checksum: expected {}, got {}", expected, actual) + display("The packfiles checksum didn't match the index file checksum: expected {}, got {}", expected, actual) } PackObjectMismatch { expected: git_object::Id, actual: git_object::Id, offset: u64, kind: git_object::Kind} { - display("The SHA1 of {} object at offset {} didn't match the checksum in the index data: expected {}, got {}", kind, offset, expected, actual) + display("The SHA1 of {} object at offset {} didn't match the checksum in the index file: expected {}, got {}", kind, offset, expected, actual) } Crc32Mismatch { expected: u32, actual: u32, offset: u64, kind: git_object::Kind} { - display("The CRC32 of {} object at offset {} didn't match the checksum in the index data: expected {}, got {}", kind, offset, expected, actual) + display("The CRC32 of {} object at offset {} didn't match the checksum in the index file: expected {}, got {}", kind, offset, expected, actual) } } } @@ -76,7 +76,7 @@ pub struct Outcome { pub pack_size: u64, } -/// Verify and validate the content of the index data +/// Verify and validate the content of the index file impl index::File { pub fn checksum_of_index(&self) -> git_object::Id { git_object::Id::from_20_bytes(&self.data[self.data.len() - SHA1_SIZE..]) diff --git a/gitoxide-core/src/lib.rs b/gitoxide-core/src/lib.rs index 29500848d0f..f6fb9e6b2c5 100644 --- a/gitoxide-core/src/lib.rs +++ b/gitoxide-core/src/lib.rs @@ -114,17 +114,17 @@ where })?; let res = match ext { "pack" => { - let pack = git_odb::pack::data::File::at(path).with_context(|| "Could not open pack data")?; + let pack = git_odb::pack::data::File::at(path).with_context(|| "Could not open pack file")?; pack.verify_checksum().map(|id| (id, None))? } "idx" => { - let idx = git_odb::pack::index::File::at(path).with_context(|| "Could not open pack index data")?; + let idx = git_odb::pack::index::File::at(path).with_context(|| "Could not open pack index file")?; let packfile_path = path.with_extension("pack"); let pack = git_odb::pack::data::File::at(&packfile_path) .or_else(|e| { writeln!( err, - "Could not find matching pack data at '{}' - only index data will be verified, error was: {}", + "Could not find matching pack file at '{}' - only index file will be verified, error was: {}", packfile_path.display(), e ) diff --git a/src/plumbing/pretty.rs b/src/plumbing/pretty.rs index a43f326ef21..c399cff8c17 100644 --- a/src/plumbing/pretty.rs +++ b/src/plumbing/pretty.rs @@ -26,7 +26,7 @@ mod options { #[derive(Debug, StructOpt)] pub enum Subcommands { - /// Verify the integrity of a pack or index data + /// Verify the integrity of a pack or index file #[structopt(setting = AppSettings::ColoredHelp)] VerifyPack { /// output statistical information about the pack