Unified · Split
| @@ -15,7 +15,7 @@ use gitoxide_core::pack::verify; · 14 unmodified lines | |||
| 15 | #[cfg(any(feature = "gitoxide-core-async-client", feature = "gitoxide-core-blocking-client"))] | 15 | #[cfg(any(feature = "gitoxide-core-async-client", feature = "gitoxide-core-blocking-client"))] |
| 16 | use crate::plumbing::options::remote; | 16 | use crate::plumbing::options::remote; |
| 17 | use crate::{ | 17 | use crate::{ |
| 18 | plumbing::options::{commitgraph, Args, Subcommands}, | 18 | plumbing::options::{commitgraph, pack, Args, Subcommands}, |
| 19 | shared::pretty::prepare_and_run, | 19 | shared::pretty::prepare_and_run, |
| 20 | }; | 20 | }; |
| 21 | 21 | ||
| @@ -72,111 +72,215 @@ pub fn main() -> Result<()> { · 50 unmodified lines | |||
| 72 | })?; | 72 | })?; |
| 73 | 73 | ||
| 74 | match cmd { | 74 | match cmd { |
| 75 | Subcommands::PackCreate { | 75 | Subcommands::Pack(subcommands) => match subcommands { |
| 76 | repository, | 76 | pack::Subcommands::Create { |
| 77 | expansion, | 77 | repository, |
| 78 | thin, | 78 | expansion, |
| 79 | statistics, | 79 | thin, |
| 80 | nondeterministic_count, | 80 | statistics, |
| 81 | tips, | 81 | nondeterministic_count, |
| 82 | pack_cache_size_mb, | 82 | tips, |
| 83 | object_cache_size_mb, | 83 | pack_cache_size_mb, |
| 84 | output_directory, | 84 | object_cache_size_mb, |
| 85 | } => { | 85 | output_directory, |
| 86 | let has_tips = !tips.is_empty(); | 86 | } => { |
| 87 | prepare_and_run( | 87 | let has_tips = !tips.is_empty(); |
| 88 | "pack-create", | 88 | prepare_and_run( |
| 89 | verbose, | 89 | "pack-create", |
| 90 | progress, | 90 | verbose, |
| 91 | progress_keep_open, | 91 | progress, |
| 92 | core::pack::create::PROGRESS_RANGE, | 92 | progress_keep_open, |
| 93 | move |progress, out, _err| { | 93 | core::pack::create::PROGRESS_RANGE, |
| 94 | let input = if has_tips { | 94 | move |progress, out, _err| { |
| 95 | None | 95 | let input = if has_tips { |
| 96 | } else { | 96 | None |
| 97 | if atty::is(atty::Stream::Stdin) { | ||
| 98 | anyhow::bail!( | ||
| 99 | "Refusing to read from standard input as no path is given, but it's a terminal." | ||
| 100 | ) | ||
| 101 | } | ||
| 102 | Some(BufReader::new(stdin())) | ||
| 103 | }; | ||
| 104 | let repository = repository.unwrap_or_else(|| PathBuf::from(".")); | ||
| 105 | let context = core::pack::create::Context { | ||
| 106 | thread_limit, | ||
| 107 | thin, | ||
| 108 | nondeterministic_count, | ||
| 109 | pack_cache_size_in_bytes: pack_cache_size_mb.unwrap_or(0) * 1_000_000, | ||
| 110 | object_cache_size_in_bytes: object_cache_size_mb.unwrap_or(0) * 1_000_000, | ||
| 111 | statistics: if statistics { Some(format) } else { None }, | ||
| 112 | out, | ||
| 113 | expansion: expansion.unwrap_or(if has_tips { | ||
| 114 | core::pack::create::ObjectExpansion::TreeTraversal | ||
| 115 | } else { | 97 | } else { |
| 116 | core::pack::create::ObjectExpansion::None | 98 | if atty::is(atty::Stream::Stdin) { |
| 117 | }), | 99 | anyhow::bail!( |
| 118 | }; | 100 | "Refusing to read from standard input as no path is given, but it's a terminal." |
| 119 | core::pack::create(repository, tips, input, output_directory, progress, context) | 101 | ) |
| 120 | }, | 102 | } |
| 121 | ) | 103 | Some(BufReader::new(stdin())) |
| 122 | } | 104 | }; |
| 123 | #[cfg(feature = "gitoxide-core-async-client")] | 105 | let repository = repository.unwrap_or_else(|| PathBuf::from(".")); |
| 124 | Subcommands::PackReceive { | 106 | let context = core::pack::create::Context { |
| 125 | protocol, | 107 | thread_limit, |
| 126 | url, | 108 | thin, |
| 127 | directory, | 109 | nondeterministic_count, |
| 128 | refs, | 110 | pack_cache_size_in_bytes: pack_cache_size_mb.unwrap_or(0) * 1_000_000, |
| 129 | refs_directory, | 111 | object_cache_size_in_bytes: object_cache_size_mb.unwrap_or(0) * 1_000_000, |
| 130 | } => { | 112 | statistics: if statistics { Some(format) } else { None }, |
| 131 | let (_handle, progress) = async_util::prepare(verbose, "pack-receive", core::pack::receive::PROGRESS_RANGE); | 113 | out, |
| 132 | let fut = core::pack::receive( | 114 | expansion: expansion.unwrap_or(if has_tips { |
| 115 | core::pack::create::ObjectExpansion::TreeTraversal | ||
| 116 | } else { | ||
| 117 | core::pack::create::ObjectExpansion::None | ||
| 118 | }), | ||
| 119 | }; | ||
| 120 | core::pack::create(repository, tips, input, output_directory, progress, context) | ||
| 121 | }, | ||
| 122 | ) | ||
| 123 | } | ||
| 124 | #[cfg(feature = "gitoxide-core-async-client")] | ||
| 125 | pack::Subcommands::Receive { | ||
| 133 | protocol, | 126 | protocol, |
| 134 | &url, | 127 | url, |
| 135 | directory, | 128 | directory, |
| 129 | refs, | ||
| 136 | refs_directory, | 130 | refs_directory, |
| 137 | refs.into_iter().map(|s| s.into()).collect(), | 131 | } => { |
| 138 | git_features::progress::DoOrDiscard::from(progress), | 132 | let (_handle, progress) = |
| 139 | core::pack::receive::Context { | 133 | async_util::prepare(verbose, "pack-receive", core::pack::receive::PROGRESS_RANGE); |
| 140 | thread_limit, | 134 | let fut = core::pack::receive( |
| 141 | format, | ||
| 142 | out: std::io::stdout(), | ||
| 143 | should_interrupt, | ||
| 144 | }, | ||
| 145 | ); | ||
| 146 | return futures_lite::future::block_on(fut); | ||
| 147 | } | ||
| 148 | #[cfg(feature = "gitoxide-core-blocking-client")] | ||
| 149 | Subcommands::PackReceive { | ||
| 150 | protocol, | ||
| 151 | url, | ||
| 152 | directory, | ||
| 153 | refs, | ||
| 154 | refs_directory, | ||
| 155 | } => prepare_and_run( | ||
| 156 | "pack-receive", | ||
| 157 | verbose, | ||
| 158 | progress, | ||
| 159 | progress_keep_open, | ||
| 160 | core::pack::receive::PROGRESS_RANGE, | ||
| 161 | move |progress, out, _err| { | ||
| 162 | core::pack::receive( | ||
| 163 | protocol, | 135 | protocol, |
| 164 | &url, | 136 | &url, |
| 165 | directory, | 137 | directory, |
| 166 | refs_directory, | 138 | refs_directory, |
| 167 | refs.into_iter().map(|r| r.into()).collect(), | 139 | refs.into_iter().map(|s| s.into()).collect(), |
| 168 | git_features::progress::DoOrDiscard::from(progress), | 140 | git_features::progress::DoOrDiscard::from(progress), |
| 169 | core::pack::receive::Context { | 141 | core::pack::receive::Context { |
| 170 | thread_limit, | 142 | thread_limit, |
| 171 | format, | 143 | format, |
| 144 | out: std::io::stdout(), | ||
| 172 | should_interrupt, | 145 | should_interrupt, |
| 173 | out, | ||
| 174 | }, | 146 | }, |
| 175 | ) | 147 | ); |
| 176 | }, | 148 | return futures_lite::future::block_on(fut); |
| 177 | ), | 149 | } |
| 178 | #[cfg(feature = "gitoxide-core-async-client")] | 150 | #[cfg(feature = "gitoxide-core-blocking-client")] |
| 151 | pack::Subcommands::Receive { | ||
| 152 | protocol, | ||
| 153 | url, | ||
| 154 | directory, | ||
| 155 | refs, | ||
| 156 | refs_directory, | ||
| 157 | } => prepare_and_run( | ||
| 158 | "pack-receive", | ||
| 159 | verbose, | ||
| 160 | progress, | ||
| 161 | progress_keep_open, | ||
| 162 | core::pack::receive::PROGRESS_RANGE, | ||
| 163 | move |progress, out, _err| { | ||
| 164 | core::pack::receive( | ||
| 165 | protocol, | ||
| 166 | &url, | ||
| 167 | directory, | ||
| 168 | refs_directory, | ||
| 169 | refs.into_iter().map(|r| r.into()).collect(), | ||
| 170 | git_features::progress::DoOrDiscard::from(progress), | ||
| 171 | core::pack::receive::Context { | ||
| 172 | thread_limit, | ||
| 173 | format, | ||
| 174 | should_interrupt, | ||
| 175 | out, | ||
| 176 | }, | ||
| 177 | ) | ||
| 178 | }, | ||
| 179 | ), | ||
| 180 | pack::Subcommands::IndexFromData { | ||
| 181 | iteration_mode, | ||
| 182 | pack_path, | ||
| 183 | directory, | ||
| 184 | } => prepare_and_run( | ||
| 185 | "pack-index-from-data", | ||
| 186 | verbose, | ||
| 187 | progress, | ||
| 188 | progress_keep_open, | ||
| 189 | core::pack::index::PROGRESS_RANGE, | ||
| 190 | move |progress, out, _err| { | ||
| 191 | use gitoxide_core::pack::index::PathOrRead; | ||
| 192 | let input = if let Some(path) = pack_path { | ||
| 193 | PathOrRead::Path(path) | ||
| 194 | } else { | ||
| 195 | if atty::is(atty::Stream::Stdin) { | ||
| 196 | anyhow::bail!( | ||
| 197 | "Refusing to read from standard input as no path is given, but it's a terminal." | ||
| 198 | ) | ||
| 199 | } | ||
| 200 | PathOrRead::Read(Box::new(std::io::stdin())) | ||
| 201 | }; | ||
| 202 | core::pack::index::from_pack( | ||
| 203 | input, | ||
| 204 | directory, | ||
| 205 | progress, | ||
| 206 | core::pack::index::Context { | ||
| 207 | thread_limit, | ||
| 208 | iteration_mode, | ||
| 209 | format, | ||
| 210 | out, | ||
| 211 | should_interrupt: &git_repository::interrupt::IS_INTERRUPTED, | ||
| 212 | }, | ||
| 213 | ) | ||
| 214 | }, | ||
| 215 | ), | ||
| 216 | pack::Subcommands::Explode { | ||
| 217 | check, | ||
| 218 | sink_compress, | ||
| 219 | delete_pack, | ||
| 220 | pack_path, | ||
| 221 | object_path, | ||
| 222 | verify, | ||
| 223 | } => prepare_and_run( | ||
| 224 | "pack-explode", | ||
| 225 | verbose, | ||
| 226 | progress, | ||
| 227 | progress_keep_open, | ||
| 228 | None, | ||
| 229 | move |progress, _out, _err| { | ||
| 230 | core::pack::explode::pack_or_pack_index( | ||
| 231 | pack_path, | ||
| 232 | object_path, | ||
| 233 | check, | ||
| 234 | progress, | ||
| 235 | core::pack::explode::Context { | ||
| 236 | thread_limit, | ||
| 237 | delete_pack, | ||
| 238 | sink_compress, | ||
| 239 | verify, | ||
| 240 | should_interrupt, | ||
| 241 | }, | ||
| 242 | ) | ||
| 243 | }, | ||
| 244 | ), | ||
| 245 | pack::Subcommands::Verify { | ||
| 246 | path, | ||
| 247 | algorithm, | ||
| 248 | decode, | ||
| 249 | re_encode, | ||
| 250 | statistics, | ||
| 251 | } => prepare_and_run( | ||
| 252 | "pack-verify", | ||
| 253 | verbose, | ||
| 254 | progress, | ||
| 255 | progress_keep_open, | ||
| 256 | verify::PROGRESS_RANGE, | ||
| 257 | move |progress, out, err| { | ||
| 258 | let mode = match (decode, re_encode) { | ||
| 259 | (true, false) => verify::Mode::HashCrc32Decode, | ||
| 260 | (true, true) | (false, true) => verify::Mode::HashCrc32DecodeEncode, | ||
| 261 | (false, false) => verify::Mode::HashCrc32, | ||
| 262 | }; | ||
| 263 | let output_statistics = if statistics { Some(format) } else { None }; | ||
| 264 | verify::pack_or_pack_index( | ||
| 265 | path, | ||
| 266 | progress, | ||
| 267 | verify::Context { | ||
| 268 | output_statistics, | ||
| 269 | out, | ||
| 270 | err, | ||
| 271 | thread_limit, | ||
| 272 | mode, | ||
| 273 | algorithm, | ||
| 274 | should_interrupt: &should_interrupt, | ||
| 275 | }, | ||
| 276 | ) | ||
| 277 | }, | ||
| 278 | ) | ||
| 279 | .map(|_| ()), | ||
| 280 | }, | ||
| 281 | #[cfg(any(feature = "gitoxide-core-async-client", feature = "gitoxide-core-blocking-client"))] | ||
| 179 | Subcommands::Remote(subcommands) => match subcommands { | 282 | Subcommands::Remote(subcommands) => match subcommands { |
| 283 | #[cfg(feature = "gitoxide-core-async-client")] | ||
| 180 | remote::Subcommands::RefList { protocol, url } => { | 284 | remote::Subcommands::RefList { protocol, url } => { |
| 181 | let (_handle, progress) = | 285 | let (_handle, progress) = |
| 182 | async_util::prepare(verbose, "remote-ref-list", Some(core::remote::refs::PROGRESS_RANGE)); | 286 | async_util::prepare(verbose, "remote-ref-list", Some(core::remote::refs::PROGRESS_RANGE)); |
| @@ -192,9 +296,7 @@ pub fn main() -> Result<()> { · 9 unmodified lines | |||
| 192 | ); | 296 | ); |
| 193 | return futures_lite::future::block_on(fut); | 297 | return futures_lite::future::block_on(fut); |
| 194 | } | 298 | } |
| 195 | }, | 299 | #[cfg(feature = "gitoxide-core-blocking-client")] |
| 196 | #[cfg(feature = "gitoxide-core-blocking-client")] | ||
| 197 | Subcommands::Remote(subcommands) => match subcommands { | ||
| 198 | remote::Subcommands::RefList { protocol, url } => prepare_and_run( | 300 | remote::Subcommands::RefList { protocol, url } => prepare_and_run( |
| 199 | "remote-ref-list", | 301 | "remote-ref-list", |
| 200 | verbose, | 302 | verbose, |
| @@ -215,104 +317,6 @@ pub fn main() -> Result<()> { · 14 unmodified lines | |||
| 215 | }, | 317 | }, |
| 216 | ), | 318 | ), |
| 217 | }, | 319 | }, |
| 218 | Subcommands::PackIndexFromData { | ||
| 219 | iteration_mode, | ||
| 220 | pack_path, | ||
| 221 | directory, | ||
| 222 | } => prepare_and_run( | ||
| 223 | "pack-index-from-data", | ||
| 224 | verbose, | ||
| 225 | progress, | ||
| 226 | progress_keep_open, | ||
| 227 | core::pack::index::PROGRESS_RANGE, | ||
| 228 | move |progress, out, _err| { | ||
| 229 | use gitoxide_core::pack::index::PathOrRead; | ||
| 230 | let input = if let Some(path) = pack_path { | ||
| 231 | PathOrRead::Path(path) | ||
| 232 | } else { | ||
| 233 | if atty::is(atty::Stream::Stdin) { | ||
| 234 | anyhow::bail!("Refusing to read from standard input as no path is given, but it's a terminal.") | ||
| 235 | } | ||
| 236 | PathOrRead::Read(Box::new(std::io::stdin())) | ||
| 237 | }; | ||
| 238 | core::pack::index::from_pack( | ||
| 239 | input, | ||
| 240 | directory, | ||
| 241 | progress, | ||
| 242 | core::pack::index::Context { | ||
| 243 | thread_limit, | ||
| 244 | iteration_mode, | ||
| 245 | format, | ||
| 246 | out, | ||
| 247 | should_interrupt: &git_repository::interrupt::IS_INTERRUPTED, | ||
| 248 | }, | ||
| 249 | ) | ||
| 250 | }, | ||
| 251 | ), | ||
| 252 | Subcommands::PackExplode { | ||
| 253 | check, | ||
| 254 | sink_compress, | ||
| 255 | delete_pack, | ||
| 256 | pack_path, | ||
| 257 | object_path, | ||
| 258 | verify, | ||
| 259 | } => prepare_and_run( | ||
| 260 | "pack-explode", | ||
| 261 | verbose, | ||
| 262 | progress, | ||
| 263 | progress_keep_open, | ||
| 264 | None, | ||
| 265 | move |progress, _out, _err| { | ||
| 266 | core::pack::explode::pack_or_pack_index( | ||
| 267 | pack_path, | ||
| 268 | object_path, | ||
| 269 | check, | ||
| 270 | progress, | ||
| 271 | core::pack::explode::Context { | ||
| 272 | thread_limit, | ||
| 273 | delete_pack, | ||
| 274 | sink_compress, | ||
| 275 | verify, | ||
| 276 | should_interrupt, | ||
| 277 | }, | ||
| 278 | ) | ||
| 279 | }, | ||
| 280 | ), | ||
| 281 | Subcommands::PackVerify { | ||
| 282 | path, | ||
| 283 | algorithm, | ||
| 284 | decode, | ||
| 285 | re_encode, | ||
| 286 | statistics, | ||
| 287 | } => prepare_and_run( | ||
| 288 | "pack-verify", | ||
| 289 | verbose, | ||
| 290 | progress, | ||
| 291 | progress_keep_open, | ||
| 292 | verify::PROGRESS_RANGE, | ||
| 293 | move |progress, out, err| { | ||
| 294 | let mode = match (decode, re_encode) { | ||
| 295 | (true, false) => verify::Mode::HashCrc32Decode, | ||
| 296 | (true, true) | (false, true) => verify::Mode::HashCrc32DecodeEncode, | ||
| 297 | (false, false) => verify::Mode::HashCrc32, | ||
| 298 | }; | ||
| 299 | let output_statistics = if statistics { Some(format) } else { None }; | ||
| 300 | verify::pack_or_pack_index( | ||
| 301 | path, | ||
| 302 | progress, | ||
| 303 | verify::Context { | ||
| 304 | output_statistics, | ||
| 305 | out, | ||
| 306 | err, | ||
| 307 | thread_limit, | ||
| 308 | mode, | ||
| 309 | algorithm, | ||
| 310 | should_interrupt: &should_interrupt, | ||
| 311 | }, | ||
| 312 | ) | ||
| 313 | }, | ||
| 314 | ) | ||
| 315 | .map(|_| ()), | ||
| 316 | Subcommands::Commitgraph(subcommands) => match subcommands { | 320 | Subcommands::Commitgraph(subcommands) => match subcommands { |
| 317 | commitgraph::Subcommands::Verify { path, statistics } => prepare_and_run( | 321 | commitgraph::Subcommands::Verify { path, statistics } => prepare_and_run( |
| 318 | "commit-graph-verify", | 322 | "commit-graph-verify", |
| @@ -1,5 +1,3 @@ | |||
| 1 | use std::{ffi::OsString, path::PathBuf}; | ||
| 2 | |||
| 3 | use clap::AppSettings; | 1 | use clap::AppSettings; |
| 4 | use gitoxide_core as core; | 2 | use gitoxide_core as core; |
| 5 | 3 | ||
| @@ -44,203 +42,225 @@ pub struct Args { · 38 unmodified lines | |||
| 44 | 42 | ||
| 45 | #[derive(Debug, clap::Parser)] | 43 | #[derive(Debug, clap::Parser)] |
| 46 | pub enum Subcommands { | 44 | pub enum Subcommands { |
| 47 | #[clap(setting = AppSettings::DisableVersionFlag)] | 45 | /// Subcommands for interacting with packs and their indices. |
| 48 | PackCreate { | 46 | #[clap(subcommand)] |
| 49 | #[clap(long, short = 'r')] | 47 | Pack(pack::Subcommands), |
| 50 | /// the directory containing the '.git' repository from which objects should be read. | 48 | /// Subcommands for interacting with git remotes, e.g. git repositories hosted on servers. |
| 51 | repository: Option<PathBuf>, | 49 | #[clap(subcommand)] |
| 52 | 50 | #[cfg(any(feature = "gitoxide-core-async-client", feature = "gitoxide-core-blocking-client"))] | |
| 53 | #[clap(long, short = 'e', possible_values(core::pack::create::ObjectExpansion::variants()))] | 51 | Remote(remote::Subcommands), |
| 54 | /// the way objects are expanded. They differ in costs. | 52 | /// Subcommands for interacting with commitgraphs |
| 55 | /// | 53 | #[clap(subcommand)] |
| 56 | /// Possible values are "none" and "tree-traversal". Default is "none". | 54 | Commitgraph(commitgraph::Subcommands), |
| 57 | expansion: Option<core::pack::create::ObjectExpansion>, | 55 | } |
| 58 | 56 | ||
| 59 | #[clap(long)] | 57 | /// |
| 60 | /// if set, the counting phase may be accelerated using multithreading. | 58 | pub mod pack { |
| 61 | /// | 59 | use clap::AppSettings; |
| 62 | /// On the flip side, however, one will loose deterministic counting results which affects the | 60 | use gitoxide_core as core; |
| 63 | /// way the resulting pack is structured. | 61 | use std::ffi::OsString; |
| 64 | nondeterministic_count: bool, | 62 | use std::path::PathBuf; |
| 65 | |||
| 66 | #[clap(long, short = 's')] | ||
| 67 | /// If set statistical information will be presented to inform about pack creation details. | ||
| 68 | /// It's a form of instrumentation for developers to help improve pack generation. | ||
| 69 | statistics: bool, | ||
| 70 | |||
| 71 | #[clap(long)] | ||
| 72 | /// The size in megabytes for a cache to speed up pack access for packs with long delta chains. | ||
| 73 | /// It is shared among all threads, so 4 threads would use their own cache 1/4th of the size. | ||
| 74 | /// | ||
| 75 | /// If unset, no cache will be used. | ||
| 76 | pack_cache_size_mb: Option<usize>, | ||
| 77 | 63 | ||
| 78 | #[clap(long)] | 64 | #[derive(Debug, clap::Parser)] |
| 79 | /// The size in megabytes for a cache to speed up accessing entire objects, bypassing object database access when hit. | 65 | pub enum Subcommands { |
| 80 | /// It is shared among all threads, so 4 threads would use their own cache 1/4th of the size. | 66 | /// Create a new pack with a set of objects. |
| 81 | /// | 67 | #[clap(setting = AppSettings::DisableVersionFlag)] |
| 82 | /// This cache type is currently only effective when using the 'diff-tree' object expansion. | 68 | Create { |
| 83 | /// | 69 | #[clap(long, short = 'r')] |
| 84 | /// If unset, no cache will be used. | 70 | /// the directory containing the '.git' repository from which objects should be read. |
| 85 | object_cache_size_mb: Option<usize>, | 71 | repository: Option<PathBuf>, |
| 86 | 72 | ||
| 87 | #[clap(long)] | 73 | #[clap(long, short = 'e', possible_values(core::pack::create::ObjectExpansion::variants()))] |
| 88 | /// if set, delta-objects whose base object wouldn't be in the pack will not be recompressed as base object, but instead | 74 | /// the way objects are expanded. They differ in costs. |
| 89 | /// refer to its base object using its object id. | 75 | /// |
| 90 | /// | 76 | /// Possible values are "none" and "tree-traversal". Default is "none". |
| 91 | /// This allows for smaller packs but requires the receiver of the pack to resolve these ids before storing the pack. | 77 | expansion: Option<core::pack::create::ObjectExpansion>, |
| 92 | /// Packs produced with this option enabled are only valid in transit, but not at rest. | ||
| 93 | thin: bool, | ||
| 94 | 78 | ||
| 95 | /// The directory into which to write the pack file. | 79 | #[clap(long)] |
| 96 | #[clap(long, short = 'o')] | 80 | /// if set, the counting phase may be accelerated using multithreading. |
| 97 | output_directory: Option<PathBuf>, | 81 | /// |
| 82 | /// On the flip side, however, one will loose deterministic counting results which affects the | ||
| 83 | /// way the resulting pack is structured. | ||
| 84 | nondeterministic_count: bool, | ||
| 98 | 85 | ||
| 99 | /// The tips from which to start the commit graph iteration, either as fully qualified commit hashes | 86 | #[clap(long, short = 's')] |
| 100 | /// or as branch names. | 87 | /// If set statistical information will be presented to inform about pack creation details. |
| 101 | /// | 88 | /// It's a form of instrumentation for developers to help improve pack generation. |
| 102 | /// If empty, we expect to read objects on stdin and default to 'none' as expansion mode. | 89 | statistics: bool, |
| 103 | /// Otherwise the expansion mode is 'tree-traversal' by default. | ||
| 104 | tips: Vec<OsString>, | ||
| 105 | }, | ||
| 106 | #[clap(setting = AppSettings::DisableVersionFlag)] | ||
| 107 | #[cfg(any(feature = "gitoxide-core-async-client", feature = "gitoxide-core-blocking-client"))] | ||
| 108 | PackReceive { | ||
| 109 | /// The protocol version to use. Valid values are 1 and 2 | ||
| 110 | #[clap(long, short = 'p')] | ||
| 111 | protocol: Option<core::net::Protocol>, | ||
| 112 | 90 | ||
| 113 | /// the directory into which to write references. Existing files will be overwritten. | 91 | #[clap(long)] |
| 114 | /// | 92 | /// The size in megabytes for a cache to speed up pack access for packs with long delta chains. |
| 115 | /// Note that the directory will be created if needed. | 93 | /// It is shared among all threads, so 4 threads would use their own cache 1/4th of the size. |
| 116 | #[clap(long, short = 'd')] | 94 | /// |
| 117 | refs_directory: Option<PathBuf>, | 95 | /// If unset, no cache will be used. |
| 96 | pack_cache_size_mb: Option<usize>, | ||
| 118 | 97 | ||
| 119 | /// The URLs or path from which to receive the pack. | 98 | #[clap(long)] |
| 120 | /// | 99 | /// The size in megabytes for a cache to speed up accessing entire objects, bypassing object database access when hit. |
| 121 | /// See here for a list of supported URLs: <https://www.git-scm.com/docs/git-clone#_git_urls> | 100 | /// It is shared among all threads, so 4 threads would use their own cache 1/4th of the size. |
| 122 | url: String, | 101 | /// |
| 102 | /// This cache type is currently only effective when using the 'diff-tree' object expansion. | ||
| 103 | /// | ||
| 104 | /// If unset, no cache will be used. | ||
| 105 | object_cache_size_mb: Option<usize>, | ||
| 123 | 106 | ||
| 124 | /// If set once or more times, these references will be fetched instead of all advertised ones. | 107 | #[clap(long)] |
| 125 | /// | 108 | /// if set, delta-objects whose base object wouldn't be in the pack will not be recompressed as base object, but instead |
| 126 | /// Note that this requires a reasonably modern git server. | 109 | /// refer to its base object using its object id. |
| 127 | #[clap(long = "reference", short = 'r')] | 110 | /// |
| 128 | refs: Vec<String>, | 111 | /// This allows for smaller packs but requires the receiver of the pack to resolve these ids before storing the pack. |
| 112 | /// Packs produced with this option enabled are only valid in transit, but not at rest. | ||
| 113 | thin: bool, | ||
| 129 | 114 | ||
| 130 | /// The directory into which to write the received pack and index. | 115 | /// The directory into which to write the pack file. |
| 131 | /// | 116 | #[clap(long, short = 'o')] |
| 132 | /// If unset, they will be discarded. | 117 | output_directory: Option<PathBuf>, |
| 133 | directory: Option<PathBuf>, | ||
| 134 | }, | ||
| 135 | /// Subcommands for interacting with git remotes, e.g. git repositories hosted on servers. | ||
| 136 | #[clap(subcommand)] | ||
| 137 | #[cfg(any(feature = "gitoxide-core-async-client", feature = "gitoxide-core-blocking-client"))] | ||
| 138 | Remote(remote::Subcommands), | ||
| 139 | #[clap(setting = AppSettings::DisableVersionFlag)] | ||
| 140 | PackIndexFromData { | ||
| 141 | /// Specify how to iterate the pack, defaults to 'verify' | ||
| 142 | /// | ||
| 143 | /// Valid values are | ||
| 144 | /// | ||
| 145 | /// **as-is** do not do anything and expect the pack file to be valid as per the trailing hash, | ||
| 146 | /// **verify** the input ourselves and validate that it matches with the hash provided in the pack, | ||
| 147 | /// **restore** hash the input ourselves and ignore failing entries, instead finish the pack with the hash we computed | ||
| 148 | #[clap( | ||
| 149 | long, | ||
| 150 | short = 'i', | ||
| 151 | default_value = "verify", | ||
| 152 | possible_values(core::pack::index::IterationMode::variants()) | ||
| 153 | )] | ||
| 154 | iteration_mode: core::pack::index::IterationMode, | ||
| 155 | |||
| 156 | /// Path to the pack file to read (with .pack extension). | ||
| 157 | /// | ||
| 158 | /// If unset, the pack file is expected on stdin. | ||
| 159 | #[clap(long, short = 'p')] | ||
| 160 | pack_path: Option<PathBuf>, | ||
| 161 | 118 | ||
| 162 | /// The folder into which to place the pack and the generated index file | 119 | /// The tips from which to start the commit graph iteration, either as fully qualified commit hashes |
| 163 | /// | 120 | /// or as branch names. |
| 164 | /// If unset, only informational output will be provided to standard output. | 121 | /// |
| 165 | #[clap(parse(from_os_str))] | 122 | /// If empty, we expect to read objects on stdin and default to 'none' as expansion mode. |
| 166 | directory: Option<PathBuf>, | 123 | /// Otherwise the expansion mode is 'tree-traversal' by default. |
| 167 | }, | 124 | tips: Vec<OsString>, |
| 168 | /// Verify the integrity of a pack or index file | 125 | }, |
| 169 | #[clap(setting = AppSettings::DisableVersionFlag)] | 126 | /// Use the git-protocol to receive a pack, emulating a clone. |
| 170 | PackExplode { | 127 | #[clap(setting = AppSettings::DisableVersionFlag)] |
| 171 | #[clap(long)] | 128 | #[cfg(any(feature = "gitoxide-core-async-client", feature = "gitoxide-core-blocking-client"))] |
| 172 | /// Read written objects back and assert they match their source. Fail the operation otherwise. | 129 | Receive { |
| 173 | /// | 130 | /// The protocol version to use. Valid values are 1 and 2 |
| 174 | /// Only relevant if an object directory is set. | 131 | #[clap(long, short = 'p')] |
| 175 | verify: bool, | 132 | protocol: Option<core::net::Protocol>, |
| 176 | 133 | ||
| 177 | /// delete the pack and index file after the operation is successful | 134 | /// the directory into which to write references. Existing files will be overwritten. |
| 178 | #[clap(long)] | 135 | /// |
| 179 | delete_pack: bool, | 136 | /// Note that the directory will be created if needed. |
| 180 | 137 | #[clap(long, short = 'd')] | |
| 181 | /// The amount of checks to run | 138 | refs_directory: Option<PathBuf>, |
| 182 | #[clap( | 139 | |
| 183 | long, | 140 | /// The URLs or path from which to receive the pack. |
| 184 | short = 'c', | 141 | /// |
| 185 | default_value = "all", | 142 | /// See here for a list of supported URLs: <https://www.git-scm.com/docs/git-clone#_git_urls> |
| 186 | possible_values(core::pack::explode::SafetyCheck::variants()) | 143 | url: String, |
| 187 | )] | 144 | |
| 188 | check: core::pack::explode::SafetyCheck, | 145 | /// If set once or more times, these references will be fetched instead of all advertised ones. |
| 189 | 146 | /// | |
| 190 | /// Compress bytes even when using the sink, i.e. no object directory is specified | 147 | /// Note that this requires a reasonably modern git server. |
| 191 | /// | 148 | #[clap(long = "reference", short = 'r')] |
| 192 | /// This helps to determine overhead related to compression. If unset, the sink will | 149 | refs: Vec<String>, |
| 193 | /// only create hashes from bytes, which is usually limited by the speed at which input | 150 | |
| 194 | /// can be obtained. | 151 | /// The directory into which to write the received pack and index. |
| 195 | #[clap(long)] | 152 | /// |
| 196 | sink_compress: bool, | 153 | /// If unset, they will be discarded. |
| 197 | 154 | directory: Option<PathBuf>, | |
| 198 | /// The '.pack' or '.idx' file to explode into loose objects | 155 | }, |
| 199 | #[clap(parse(from_os_str))] | 156 | /// create a pack index from a pack data file. |
| 200 | pack_path: PathBuf, | 157 | #[clap(setting = AppSettings::DisableVersionFlag)] |
| 201 | 158 | IndexFromData { | |
| 202 | /// The path into which all objects should be written. Commonly '.git/objects' | 159 | /// Specify how to iterate the pack, defaults to 'verify' |
| 203 | #[clap(parse(from_os_str))] | 160 | /// |
| 204 | object_path: Option<PathBuf>, | 161 | /// Valid values are |
| 205 | }, | 162 | /// |
| 206 | /// Verify the integrity of a pack or index file | 163 | /// **as-is** do not do anything and expect the pack file to be valid as per the trailing hash, |
| 207 | #[clap(setting = AppSettings::DisableVersionFlag)] | 164 | /// **verify** the input ourselves and validate that it matches with the hash provided in the pack, |
| 208 | PackVerify { | 165 | /// **restore** hash the input ourselves and ignore failing entries, instead finish the pack with the hash we computed |
| 209 | /// output statistical information about the pack | 166 | /// to keep as many objects as possible. |
| 210 | #[clap(long, short = 's')] | 167 | #[clap( |
| 211 | statistics: bool, | 168 | long, |
| 212 | /// The algorithm used to verify the pack. They differ in costs. | 169 | short = 'i', |
| 213 | #[clap( | 170 | default_value = "verify", |
| 214 | long, | 171 | possible_values(core::pack::index::IterationMode::variants()) |
| 215 | short = 'a', | 172 | )] |
| 216 | default_value = "less-time", | 173 | iteration_mode: core::pack::index::IterationMode, |
| 217 | possible_values(core::pack::verify::Algorithm::variants()) | 174 | |
| 218 | )] | 175 | /// Path to the pack file to read (with .pack extension). |
| 219 | algorithm: core::pack::verify::Algorithm, | 176 | /// |
| 220 | 177 | /// If unset, the pack file is expected on stdin. | |
| 221 | #[clap(long, conflicts_with("re-encode"))] | 178 | #[clap(long, short = 'p')] |
| 222 | /// Decode and parse tags, commits and trees to validate their correctness beyond hashing correctly. | 179 | pack_path: Option<PathBuf>, |
| 223 | /// | ||
| 224 | /// Malformed objects should not usually occur, but could be injected on purpose or accident. | ||
| 225 | /// This will reduce overall performance. | ||
| 226 | decode: bool, | ||
| 227 | 180 | ||
| 228 | #[clap(long)] | 181 | /// The folder into which to place the pack and the generated index file |
| 229 | /// Decode and parse tags, commits and trees to validate their correctness, and re-encode them. | 182 | /// |
| 183 | /// If unset, only informational output will be provided to standard output. | ||
| 184 | #[clap(parse(from_os_str))] | ||
| 185 | directory: Option<PathBuf>, | ||
| 186 | }, | ||
| 187 | /// Dissolve a pack into its loose objects. | ||
| 230 | /// | 188 | /// |
| 231 | /// This flag is primarily to test the implementation of encoding, and requires to decode the object first. | 189 | /// Note that this effectively removes delta compression for an average compression of 2x, creating one file per object in the process. |
| 232 | /// Encoding an object after decoding it should yield exactly the same bytes. | 190 | /// Thus this should only be done to dissolve small packs after a fetch. |
| 233 | /// This will reduce overall performance even more, as re-encoding requires to transform zero-copy objects into | 191 | #[clap(setting = AppSettings::DisableVersionFlag)] |
| 234 | /// owned objects, causing plenty of allocation to occour. | 192 | Explode { |
| 235 | re_encode: bool, | 193 | #[clap(long)] |
| 236 | 194 | /// Read written objects back and assert they match their source. Fail the operation otherwise. | |
| 237 | /// The '.pack' or '.idx' file whose checksum to validate. | 195 | /// |
| 238 | #[clap(parse(from_os_str))] | 196 | /// Only relevant if an object directory is set. |
| 239 | path: PathBuf, | 197 | verify: bool, |
| 240 | }, | 198 | |
| 241 | /// Subcommands for interacting with commitgraphs | 199 | /// delete the pack and index file after the operation is successful |
| 242 | #[clap(subcommand)] | 200 | #[clap(long)] |
| 243 | Commitgraph(commitgraph::Subcommands), | 201 | delete_pack: bool, |
| 202 | |||
| 203 | /// The amount of checks to run | ||
| 204 | #[clap( | ||
| 205 | long, | ||
| 206 | short = 'c', | ||
| 207 | default_value = "all", | ||
| 208 | possible_values(core::pack::explode::SafetyCheck::variants()) | ||
| 209 | )] | ||
| 210 | check: core::pack::explode::SafetyCheck, | ||
| 211 | |||
| 212 | /// Compress bytes even when using the sink, i.e. no object directory is specified | ||
| 213 | /// | ||
| 214 | /// This helps to determine overhead related to compression. If unset, the sink will | ||
| 215 | /// only create hashes from bytes, which is usually limited by the speed at which input | ||
| 216 | /// can be obtained. | ||
| 217 | #[clap(long)] | ||
| 218 | sink_compress: bool, | ||
| 219 | |||
| 220 | /// The '.pack' or '.idx' file to explode into loose objects | ||
| 221 | #[clap(parse(from_os_str))] | ||
| 222 | pack_path: PathBuf, | ||
| 223 | |||
| 224 | /// The path into which all objects should be written. Commonly '.git/objects' | ||
| 225 | #[clap(parse(from_os_str))] | ||
| 226 | object_path: Option<PathBuf>, | ||
| 227 | }, | ||
| 228 | /// Verify the integrity of a pack, index or multi-index file | ||
| 229 | #[clap(setting = AppSettings::DisableVersionFlag)] | ||
| 230 | Verify { | ||
| 231 | /// output statistical information about the pack | ||
| 232 | #[clap(long, short = 's')] | ||
| 233 | statistics: bool, | ||
| 234 | /// The algorithm used to verify the pack. They differ in costs. | ||
| 235 | #[clap( | ||
| 236 | long, | ||
| 237 | short = 'a', | ||
| 238 | default_value = "less-time", | ||
| 239 | possible_values(core::pack::verify::Algorithm::variants()) | ||
| 240 | )] | ||
| 241 | algorithm: core::pack::verify::Algorithm, | ||
| 242 | |||
| 243 | #[clap(long, conflicts_with("re-encode"))] | ||
| 244 | /// Decode and parse tags, commits and trees to validate their correctness beyond hashing correctly. | ||
| 245 | /// | ||
| 246 | /// Malformed objects should not usually occur, but could be injected on purpose or accident. | ||
| 247 | /// This will reduce overall performance. | ||
| 248 | decode: bool, | ||
| 249 | |||
| 250 | #[clap(long)] | ||
| 251 | /// Decode and parse tags, commits and trees to validate their correctness, and re-encode them. | ||
| 252 | /// | ||
| 253 | /// This flag is primarily to test the implementation of encoding, and requires to decode the object first. | ||
| 254 | /// Encoding an object after decoding it should yield exactly the same bytes. | ||
| 255 | /// This will reduce overall performance even more, as re-encoding requires to transform zero-copy objects into | ||
| 256 | /// owned objects, causing plenty of allocation to occour. | ||
| 257 | re_encode: bool, | ||
| 258 | |||
| 259 | /// The '.pack' or '.idx' file whose checksum to validate. | ||
| 260 | #[clap(parse(from_os_str))] | ||
| 261 | path: PathBuf, | ||
| 262 | }, | ||
| 263 | } | ||
| 244 | } | 264 | } |
| 245 | 265 | ||
| 246 | /// | 266 | /// |
| @@ -39,157 +39,384 @@ title "git-tempfile crate" · 38 unmodified lines | |||
| 39 | ) | 39 | ) |
| 40 | ) | 40 | ) |
| 41 | 41 | ||
| 42 | title "gix pack-receive" | 42 | title "gix pack" |
| 43 | (when "running 'pack-receive'" | 43 | (when "running 'pack'" |
| 44 | snapshot="$snapshot/pack-receive" | 44 | snapshot="$snapshot/pack" |
| 45 | (small-repo-in-sandbox | 45 | |
| 46 | if [[ "$kind" != 'small' ]]; then | 46 | title "gix pack receive" |
| 47 | (with "the 'receive' sub-command" | ||
| 48 | snapshot="$snapshot/receive" | ||
| 49 | (small-repo-in-sandbox | ||
| 50 | if [[ "$kind" != 'small' ]]; then | ||
| 47 | 51 | ||
| 48 | if [[ "$kind" != 'async' ]]; then | 52 | if [[ "$kind" != 'async' ]]; then |
| 49 | (with "file:// protocol" | 53 | (with "file:// protocol" |
| 50 | (with "version 1" | 54 | (with "version 1" |
| 51 | (with "NO output directory" | 55 | (with "NO output directory" |
| 52 | it "generates the correct output" && { | 56 | it "generates the correct output" && { |
| 53 | WITH_SNAPSHOT="$snapshot/file-v-any-no-output" \ | 57 | WITH_SNAPSHOT="$snapshot/file-v-any-no-output" \ |
| 54 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-receive -p 1 .git | 58 | expect_run $SUCCESSFULLY "$exe_plumbing" pack receive -p 1 .git |
| 55 | } | 59 | } |
| 60 | ) | ||
| 61 | (with "output directory" | ||
| 62 | mkdir out | ||
| 63 | it "generates the correct output" && { | ||
| 64 | WITH_SNAPSHOT="$snapshot/file-v-any-with-output" \ | ||
| 65 | expect_run $SUCCESSFULLY "$exe_plumbing" pack receive -p 1 .git out/ | ||
| 66 | } | ||
| 67 | it "creates an index and a pack in the output directory" && { | ||
| 68 | WITH_SNAPSHOT="$snapshot/ls-in-output-dir" \ | ||
| 69 | expect_run $SUCCESSFULLY ls out/ | ||
| 70 | } | ||
| 71 | (with "--write-refs set" | ||
| 72 | it "generates the correct output" && { | ||
| 73 | WITH_SNAPSHOT="$snapshot/file-v-any-with-output" \ | ||
| 74 | expect_run $SUCCESSFULLY "$exe_plumbing" pack receive -p 1 --refs-directory out/all-refs .git out/ | ||
| 75 | } | ||
| 76 | it "writes references into the refs folder of the output directory" && { | ||
| 77 | expect_snapshot "$snapshot/repo-refs" out/all-refs | ||
| 78 | } | ||
| 79 | ) | ||
| 80 | rm -Rf out | ||
| 81 | ) | ||
| 82 | if test "$kind" = "max"; then | ||
| 83 | (with "--format json" | ||
| 84 | it "generates the correct output in JSON format" && { | ||
| 85 | WITH_SNAPSHOT="$snapshot/file-v-any-no-output-json" \ | ||
| 86 | expect_run $SUCCESSFULLY "$exe_plumbing" --format json pack receive --protocol 1 .git | ||
| 87 | } | ||
| 88 | ) | ||
| 89 | fi | ||
| 56 | ) | 90 | ) |
| 57 | (with "output directory" | 91 | (with "version 2" |
| 58 | mkdir out | 92 | (with "NO output directory" |
| 59 | it "generates the correct output" && { | 93 | it "generates the correct output" && { |
| 60 | WITH_SNAPSHOT="$snapshot/file-v-any-with-output" \ | 94 | WITH_SNAPSHOT="$snapshot/file-v-any-no-output" \ |
| 61 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-receive -p 1 .git out/ | 95 | expect_run $SUCCESSFULLY "$exe_plumbing" pack receive -p 2 .git |
| 62 | } | 96 | } |
| 63 | it "creates an index and a pack in the output directory" && { | 97 | ) |
| 64 | WITH_SNAPSHOT="$snapshot/ls-in-output-dir" \ | 98 | (with "output directory" |
| 65 | expect_run $SUCCESSFULLY ls out/ | 99 | mkdir out/ |
| 66 | } | 100 | it "generates the correct output" && { |
| 67 | (with "--write-refs set" | 101 | WITH_SNAPSHOT="$snapshot/file-v-any-with-output" \ |
| 102 | expect_run $SUCCESSFULLY "$exe_plumbing" pack receive .git out/ | ||
| 103 | } | ||
| 104 | it "creates an index and a pack in the output directory" && { | ||
| 105 | WITH_SNAPSHOT="$snapshot/ls-in-output-dir" \ | ||
| 106 | expect_run $SUCCESSFULLY ls out/ | ||
| 107 | } | ||
| 108 | rm -Rf out | ||
| 109 | ) | ||
| 110 | if test "$kind" = "max"; then | ||
| 111 | (with "--format json" | ||
| 112 | it "generates the correct output in JSON format" && { | ||
| 113 | WITH_SNAPSHOT="$snapshot/file-v-any-no-output-json" \ | ||
| 114 | expect_run $SUCCESSFULLY "$exe_plumbing" --format json pack receive --protocol 2 .git | ||
| 115 | } | ||
| 116 | ) | ||
| 117 | fi | ||
| 118 | ) | ||
| 119 | ) | ||
| 120 | fi | ||
| 121 | (with "git:// protocol" | ||
| 122 | launch-git-daemon | ||
| 123 | (with "version 1" | ||
| 124 | (with "NO output directory" | ||
| 125 | (with "no wanted refs" | ||
| 126 | it "generates the correct output" && { | ||
| 127 | WITH_SNAPSHOT="$snapshot/file-v-any-no-output" \ | ||
| 128 | expect_run $SUCCESSFULLY "$exe_plumbing" pack receive -p 1 git://localhost/ | ||
| 129 | } | ||
| 130 | ) | ||
| 131 | (with "wanted refs" | ||
| 132 | it "generates the correct output" && { | ||
| 133 | WITH_SNAPSHOT="$snapshot/file-v-any-no-output-wanted-ref-p1" \ | ||
| 134 | expect_run $WITH_FAILURE "$exe_plumbing" pack receive -p 1 git://localhost/ -r =refs/heads/main | ||
| 135 | } | ||
| 136 | ) | ||
| 137 | ) | ||
| 138 | (with "output directory" | ||
| 139 | mkdir out | ||
| 68 | it "generates the correct output" && { | 140 | it "generates the correct output" && { |
| 69 | WITH_SNAPSHOT="$snapshot/file-v-any-with-output" \ | 141 | WITH_SNAPSHOT="$snapshot/file-v-any-with-output" \ |
| 70 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-receive -p 1 --refs-directory out/all-refs .git out/ | 142 | expect_run $SUCCESSFULLY "$exe_plumbing" pack receive -p 1 git://localhost/ out/ |
| 71 | } | 143 | } |
| 72 | it "writes references into the refs folder of the output directory" && { | 144 | ) |
| 73 | expect_snapshot "$snapshot/repo-refs" out/all-refs | 145 | ) |
| 146 | (with "version 2" | ||
| 147 | (with "NO output directory" | ||
| 148 | (with "NO wanted refs" | ||
| 149 | it "generates the correct output" && { | ||
| 150 | WITH_SNAPSHOT="$snapshot/file-v-any-no-output" \ | ||
| 151 | expect_run $SUCCESSFULLY "$exe_plumbing" pack receive -p 2 git://localhost/ | ||
| 152 | } | ||
| 153 | ) | ||
| 154 | (with "wanted refs" | ||
| 155 | it "generates the correct output" && { | ||
| 156 | WITH_SNAPSHOT="$snapshot/file-v-any-no-output-single-ref" \ | ||
| 157 | expect_run $SUCCESSFULLY "$exe_plumbing" pack receive -p 2 git://localhost/ -r refs/heads/main | ||
| 158 | } | ||
| 159 | (when "ref does not exist" | ||
| 160 | it "fails with a detailed error message including what the server said" && { | ||
| 161 | WITH_SNAPSHOT="$snapshot/file-v-any-no-output-non-existing-single-ref" \ | ||
| 162 | expect_run $WITH_FAILURE "$exe_plumbing" pack receive -p 2 git://localhost/ -r refs/heads/does-not-exist | ||
| 163 | } | ||
| 164 | ) | ||
| 165 | ) | ||
| 166 | ) | ||
| 167 | (with "output directory" | ||
| 168 | it "generates the correct output" && { | ||
| 169 | WITH_SNAPSHOT="$snapshot/file-v-any-with-output" \ | ||
| 170 | expect_run $SUCCESSFULLY "$exe_plumbing" pack receive git://localhost/ out/ | ||
| 74 | } | 171 | } |
| 75 | ) | 172 | ) |
| 76 | rm -Rf out | ||
| 77 | ) | 173 | ) |
| 174 | ) | ||
| 175 | (on_ci | ||
| 78 | if test "$kind" = "max"; then | 176 | if test "$kind" = "max"; then |
| 79 | (with "--format json" | 177 | (with "https:// protocol" |
| 80 | it "generates the correct output in JSON format" && { | 178 | (with "version 1" |
| 81 | WITH_SNAPSHOT="$snapshot/file-v-any-no-output-json" \ | 179 | it "works" && { |
| 82 | expect_run $SUCCESSFULLY "$exe_plumbing" --format json pack-receive --protocol 1 .git | 180 | expect_run $SUCCESSFULLY "$exe_plumbing" pack receive -p 1 https://github.com/byron/gitoxide |
| 83 | } | 181 | } |
| 182 | ) | ||
| 183 | (with "version 2" | ||
| 184 | it "works" && { | ||
| 185 | expect_run $SUCCESSFULLY "$exe_plumbing" pack receive -p 2 https://github.com/byron/gitoxide | ||
| 186 | } | ||
| 187 | ) | ||
| 84 | ) | 188 | ) |
| 85 | fi | 189 | fi |
| 86 | ) | 190 | ) |
| 87 | (with "version 2" | 191 | elif [[ "$kind" = "small" ]]; then |
| 88 | (with "NO output directory" | 192 | it "fails as the CLI doesn't have networking in 'small' mode" && { |
| 89 | it "generates the correct output" && { | 193 | WITH_SNAPSHOT="$snapshot/pack receive-no-networking-in-small-failure" \ |
| 90 | WITH_SNAPSHOT="$snapshot/file-v-any-no-output" \ | 194 | expect_run 2 "$exe_plumbing" pack receive -p 1 .git |
| 91 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-receive -p 2 .git | 195 | } |
| 196 | fi | ||
| 197 | ) | ||
| 198 | ) | ||
| 199 | title "gix pack index-from-data" | ||
| 200 | (with "the 'index-from-data' sub-command" | ||
| 201 | snapshot="$snapshot/index-from-data" | ||
| 202 | PACK_FILE="$fixtures/packs/pack-11fdfa9e156ab73caae3b6da867192221f2089c2.pack" | ||
| 203 | (with "a valid and complete pack file" | ||
| 204 | (with "NO output directory specified" | ||
| 205 | (with "pack file passed as file" | ||
| 206 | it "generates an index into a sink and outputs pack and index information" && { | ||
| 207 | WITH_SNAPSHOT="$snapshot/no-output-dir-success" \ | ||
| 208 | expect_run $SUCCESSFULLY "$exe_plumbing" pack index-from-data -p "$PACK_FILE" | ||
| 92 | } | 209 | } |
| 93 | ) | 210 | ) |
| 94 | (with "output directory" | 211 | (with "pack file passed from stdin" |
| 95 | mkdir out/ | 212 | it "generates an index into a sink and outputs pack and index information" && { |
| 96 | it "generates the correct output" && { | 213 | WITH_SNAPSHOT="$snapshot/no-output-dir-success" \ |
| 97 | WITH_SNAPSHOT="$snapshot/file-v-any-with-output" \ | 214 | expect_run $SUCCESSFULLY "$exe_plumbing" pack index-from-data < "$PACK_FILE" |
| 98 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-receive .git out/ | ||
| 99 | } | 215 | } |
| 100 | it "creates an index and a pack in the output directory" && { | 216 | if test "$kind" = "max"; then |
| 101 | WITH_SNAPSHOT="$snapshot/ls-in-output-dir" \ | 217 | (with "--format json" |
| 102 | expect_run $SUCCESSFULLY ls out/ | 218 | it "generates the index into a sink and outputs information as JSON" && { |
| 219 | WITH_SNAPSHOT="$snapshot/no-output-dir-as-json-success" \ | ||
| 220 | expect_run $SUCCESSFULLY "$exe_plumbing" --format json pack index-from-data < "$PACK_FILE" | ||
| 221 | } | ||
| 222 | ) | ||
| 223 | fi | ||
| 224 | ) | ||
| 225 | ) | ||
| 226 | (sandbox | ||
| 227 | (with "with an output directory specified" | ||
| 228 | it "generates an index and outputs information" && { | ||
| 229 | WITH_SNAPSHOT="$snapshot/output-dir-success" \ | ||
| 230 | expect_run $SUCCESSFULLY "$exe_plumbing" pack index-from-data -p "$PACK_FILE" "$PWD" | ||
| 231 | } | ||
| 232 | it "writes the index and pack into the directory (they have the same names, different suffixes)" && { | ||
| 233 | WITH_SNAPSHOT="$snapshot/output-dir-content" \ | ||
| 234 | expect_run $SUCCESSFULLY ls | ||
| 103 | } | 235 | } |
| 104 | rm -Rf out | ||
| 105 | ) | 236 | ) |
| 237 | ) | ||
| 238 | ) | ||
| 239 | (with "'restore' iteration mode" | ||
| 240 | (sandbox | ||
| 241 | cp "${PACK_FILE}" . | ||
| 242 | PACK_FILE="${PACK_FILE##*/}" | ||
| 243 | "$jtt" mess-in-the-middle "${PACK_FILE}" | ||
| 244 | |||
| 245 | it "generates an index and outputs information (instead of failing)" && { | ||
| 246 | WITH_SNAPSHOT="$snapshot/output-dir-restore-success" \ | ||
| 247 | expect_run $SUCCESSFULLY "$exe_plumbing" pack index-from-data -i restore -p "$PACK_FILE" "$PWD" | ||
| 248 | } | ||
| 249 | |||
| 106 | if test "$kind" = "max"; then | 250 | if test "$kind" = "max"; then |
| 107 | (with "--format json" | 251 | (with "--format json and the very same output directory" |
| 108 | it "generates the correct output in JSON format" && { | 252 | it "generates the index, overwriting existing files, and outputs information as JSON" && { |
| 109 | WITH_SNAPSHOT="$snapshot/file-v-any-no-output-json" \ | 253 | WITH_SNAPSHOT="$snapshot/output-dir-restore-as-json-success" \ |
| 110 | expect_run $SUCCESSFULLY "$exe_plumbing" --format json pack-receive --protocol 2 .git | 254 | SNAPSHOT_FILTER=remove-paths \ |
| 255 | expect_run $SUCCESSFULLY "$exe_plumbing" --format json pack index-from-data -i restore $PWD < "$PACK_FILE" | ||
| 111 | } | 256 | } |
| 112 | ) | 257 | ) |
| 113 | fi | 258 | fi |
| 114 | ) | 259 | ) |
| 115 | ) | 260 | ) |
| 116 | fi | 261 | ) |
| 117 | (with "git:// protocol" | 262 | |
| 118 | launch-git-daemon | 263 | title "gix pack explode" |
| 119 | (with "version 1" | 264 | (with "the 'explode' sub-command" |
| 120 | (with "NO output directory" | 265 | snapshot="$snapshot/explode" |
| 121 | (with "no wanted refs" | 266 | PACK_FILE="$fixtures/packs/pack-11fdfa9e156ab73caae3b6da867192221f2089c2" |
| 122 | it "generates the correct output" && { | 267 | (with "no objects directory specified" |
| 123 | WITH_SNAPSHOT="$snapshot/file-v-any-no-output" \ | 268 | it "explodes the pack successfully and with desired output" && { |
| 124 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-receive -p 1 git://localhost/ | 269 | WITH_SNAPSHOT="$snapshot/to-sink-success" \ |
| 125 | } | 270 | expect_run $SUCCESSFULLY "$exe_plumbing" pack explode "${PACK_FILE}.idx" |
| 126 | ) | 271 | } |
| 127 | (with "wanted refs" | 272 | |
| 128 | it "generates the correct output" && { | 273 | (when "using the --delete-pack flag" |
| 129 | WITH_SNAPSHOT="$snapshot/file-v-any-no-output-wanted-ref-p1" \ | 274 | (sandbox |
| 130 | expect_run $WITH_FAILURE "$exe_plumbing" pack-receive -p 1 git://localhost/ -r =refs/heads/main | 275 | (with "a valid pack" |
| 276 | cp "${PACK_FILE}".idx "${PACK_FILE}".pack . | ||
| 277 | PACK_FILE="${PACK_FILE##*/}" | ||
| 278 | it "explodes the pack successfully and deletes the original pack and index" && { | ||
| 279 | WITH_SNAPSHOT="$snapshot/to-sink-delete-pack-success" \ | ||
| 280 | expect_run $SUCCESSFULLY "$exe_plumbing" pack explode --check skip-file-checksum --delete-pack "${PACK_FILE}.pack" | ||
| 131 | } | 281 | } |
| 132 | ) | 282 | it "removes the original files" && { |
| 133 | ) | 283 | expect_run $WITH_FAILURE test -e "${PACK_FILE}".pack |
| 134 | (with "output directory" | 284 | expect_run $WITH_FAILURE test -e "${PACK_FILE}".idx |
| 135 | mkdir out | ||
| 136 | it "generates the correct output" && { | ||
| 137 | WITH_SNAPSHOT="$snapshot/file-v-any-with-output" \ | ||
| 138 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-receive -p 1 git://localhost/ out/ | ||
| 139 | } | ||
| 140 | ) | ||
| 141 | ) | ||
| 142 | (with "version 2" | ||
| 143 | (with "NO output directory" | ||
| 144 | (with "NO wanted refs" | ||
| 145 | it "generates the correct output" && { | ||
| 146 | WITH_SNAPSHOT="$snapshot/file-v-any-no-output" \ | ||
| 147 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-receive -p 2 git://localhost/ | ||
| 148 | } | 285 | } |
| 149 | ) | 286 | ) |
| 150 | (with "wanted refs" | 287 | (with "a pack file that is invalid somewhere" |
| 151 | it "generates the correct output" && { | 288 | cp ${PACK_FILE}.idx ${PACK_FILE}.pack . |
| 152 | WITH_SNAPSHOT="$snapshot/file-v-any-no-output-single-ref" \ | 289 | PACK_FILE="${PACK_FILE##*/}" |
| 153 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-receive -p 2 git://localhost/ -r refs/heads/main | 290 | "$jtt" mess-in-the-middle "${PACK_FILE}".pack |
| 154 | } | 291 | |
| 155 | (when "ref does not exist" | 292 | (with "and all safety checks" |
| 156 | it "fails with a detailed error message including what the server said" && { | 293 | it "does not explode the file at all" && { |
| 157 | WITH_SNAPSHOT="$snapshot/file-v-any-no-output-non-existing-single-ref" \ | 294 | WITH_SNAPSHOT="$snapshot/broken-delete-pack-to-sink-failure" \ |
| 158 | expect_run $WITH_FAILURE "$exe_plumbing" pack-receive -p 2 git://localhost/ -r refs/heads/does-not-exist | 295 | expect_run $WITH_FAILURE "$exe_plumbing" pack explode --sink-compress --check all --delete-pack "${PACK_FILE}.pack" |
| 296 | } | ||
| 297 | |||
| 298 | it "did not touch index or pack file" && { | ||
| 299 | expect_exists "${PACK_FILE}".pack | ||
| 300 | expect_exists "${PACK_FILE}".idx | ||
| 159 | } | 301 | } |
| 160 | ) | 302 | ) |
| 303 | |||
| 304 | (with "and no safety checks at all (and an output directory)" | ||
| 305 | it "does explode the file" && { | ||
| 306 | WITH_SNAPSHOT="$snapshot/broken-delete-pack-to-sink-skip-checks-success" \ | ||
| 307 | expect_run $SUCCESSFULLY "$exe_plumbing" pack explode --verify --check skip-file-and-object-checksum-and-no-abort-on-decode \ | ||
| 308 | --delete-pack "${PACK_FILE}.pack" . | ||
| 309 | } | ||
| 310 | |||
| 311 | it "removes the original files" && { | ||
| 312 | expect_run $WITH_FAILURE test -e "${PACK_FILE}".pack | ||
| 313 | expect_run $WITH_FAILURE test -e "${PACK_FILE}".idx | ||
| 314 | } | ||
| 315 | |||
| 316 | (with_program tree | ||
| 317 | |||
| 318 | if test "$kind" = "small"; then | ||
| 319 | suffix=miniz-oxide | ||
| 320 | else | ||
| 321 | suffix=zlib-ng | ||
| 322 | fi | ||
| 323 | it "creates all pack objects, but the broken ones" && { | ||
| 324 | WITH_SNAPSHOT="$snapshot/broken-with-objects-dir-skip-checks-success-tree-$suffix" \ | ||
| 325 | expect_run $SUCCESSFULLY tree | ||
| 326 | } | ||
| 327 | ) | ||
| 328 | ) | ||
| 161 | ) | 329 | ) |
| 162 | ) | 330 | ) |
| 163 | (with "output directory" | ||
| 164 | it "generates the correct output" && { | ||
| 165 | WITH_SNAPSHOT="$snapshot/file-v-any-with-output" \ | ||
| 166 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-receive git://localhost/ out/ | ||
| 167 | } | ||
| 168 | ) | ||
| 169 | ) | 331 | ) |
| 170 | ) | 332 | ) |
| 171 | (on_ci | 333 | (with "a non-existing directory specified" |
| 172 | if test "$kind" = "max"; then | 334 | it "fails with a helpful error message" && { |
| 173 | (with "https:// protocol" | 335 | WITH_SNAPSHOT="$snapshot/missing-objects-dir-fail" \ |
| 174 | (with "version 1" | 336 | expect_run $WITH_FAILURE "$exe_plumbing" pack explode -c skip-file-and-object-checksum "${PACK_FILE}.idx" does-not-exist |
| 175 | it "works" && { | 337 | } |
| 176 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-receive -p 1 https://github.com/byron/gitoxide | 338 | ) |
| 339 | (with "an existing directory specified" | ||
| 340 | (sandbox | ||
| 341 | it "succeeds" && { | ||
| 342 | WITH_SNAPSHOT="$snapshot/with-objects-dir-success" \ | ||
| 343 | expect_run $SUCCESSFULLY "$exe_plumbing" pack explode -c skip-file-and-object-checksum-and-no-abort-on-decode \ | ||
| 344 | "${PACK_FILE}.pack" . | ||
| 345 | } | ||
| 346 | |||
| 347 | (with_program tree | ||
| 348 | it "creates all pack objects" && { | ||
| 349 | WITH_SNAPSHOT="$snapshot/with-objects-dir-success-tree" \ | ||
| 350 | expect_run $SUCCESSFULLY tree | ||
| 177 | } | 351 | } |
| 178 | ) | 352 | ) |
| 179 | (with "version 2" | 353 | ) |
| 180 | it "works" && { | 354 | ) |
| 181 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-receive -p 2 https://github.com/byron/gitoxide | 355 | ) |
| 356 | |||
| 357 | title "gix pack verify" | ||
| 358 | (with "the 'verify' sub-command" | ||
| 359 | snapshot="$snapshot/verify" | ||
| 360 | (with "a valid pack file" | ||
| 361 | PACK_FILE="$fixtures/packs/pack-11fdfa9e156ab73caae3b6da867192221f2089c2.pack" | ||
| 362 | it "verifies the pack successfully and with desired output" && { | ||
| 363 | WITH_SNAPSHOT="$snapshot/success" \ | ||
| 364 | expect_run $SUCCESSFULLY "$exe_plumbing" pack verify "$PACK_FILE" | ||
| 365 | } | ||
| 366 | ) | ||
| 367 | (with "a valid pack INDEX file" | ||
| 368 | PACK_INDEX_FILE="$fixtures/packs/pack-11fdfa9e156ab73caae3b6da867192221f2089c2.idx" | ||
| 369 | (with "no statistics" | ||
| 370 | it "verifies the pack index successfully and with desired output" && { | ||
| 371 | WITH_SNAPSHOT="$snapshot/index-success" \ | ||
| 372 | expect_run $SUCCESSFULLY "$exe_plumbing" pack verify "$PACK_INDEX_FILE" | ||
| 373 | } | ||
| 374 | ) | ||
| 375 | (with "statistics" | ||
| 376 | it "verifies the pack index successfully and with desired output" && { | ||
| 377 | WITH_SNAPSHOT="$snapshot/index-with-statistics-success" \ | ||
| 378 | expect_run $SUCCESSFULLY "$exe_plumbing" pack verify --statistics "$PACK_INDEX_FILE" | ||
| 379 | } | ||
| 380 | |||
| 381 | (with "and the less-memory algorithm" | ||
| 382 | it "verifies the pack index successfully and with desired output" && { | ||
| 383 | WITH_SNAPSHOT="$snapshot/index-with-statistics-success" \ | ||
| 384 | expect_run $SUCCESSFULLY "$exe_plumbing" pack verify --algorithm less-memory --statistics "$PACK_INDEX_FILE" | ||
| 182 | } | 385 | } |
| 183 | ) | 386 | ) |
| 184 | ) | 387 | ) |
| 388 | (with "decode" | ||
| 389 | it "verifies the pack index successfully and with desired output, and decodes all objects" && { | ||
| 390 | WITH_SNAPSHOT="$snapshot/index-success" \ | ||
| 391 | expect_run $SUCCESSFULLY "$exe_plumbing" pack verify --algorithm less-memory --decode "$PACK_INDEX_FILE" | ||
| 392 | } | ||
| 393 | ) | ||
| 394 | (with "re-encode" | ||
| 395 | it "verifies the pack index successfully and with desired output, and re-encodes all objects" && { | ||
| 396 | WITH_SNAPSHOT="$snapshot/index-success" \ | ||
| 397 | expect_run $SUCCESSFULLY "$exe_plumbing" pack verify --algorithm less-time --re-encode "$PACK_INDEX_FILE" | ||
| 398 | } | ||
| 399 | ) | ||
| 400 | if test "$kind" = "max"; then | ||
| 401 | (with "statistics (JSON)" | ||
| 402 | it "verifies the pack index successfully and with desired output" && { | ||
| 403 | WITH_SNAPSHOT="$snapshot/index-with-statistics-json-success" \ | ||
| 404 | expect_run $SUCCESSFULLY "$exe_plumbing" --format json --threads 1 pack verify --statistics "$PACK_INDEX_FILE" | ||
| 405 | } | ||
| 406 | ) | ||
| 185 | fi | 407 | fi |
| 186 | ) | 408 | ) |
| 187 | elif [[ "$kind" = "small" ]]; then | 409 | (sandbox |
| 188 | it "fails as the CLI doesn't have networking in 'small' mode" && { | 410 | (with "an INvalid pack INDEX file" |
| 189 | WITH_SNAPSHOT="$snapshot/pack-receive-no-networking-in-small-failure" \ | 411 | PACK_INDEX_FILE="$fixtures/packs/pack-11fdfa9e156ab73caae3b6da867192221f2089c2.idx" |
| 190 | expect_run 2 "$exe_plumbing" pack-receive -p 1 .git | 412 | cp $PACK_INDEX_FILE index.idx |
| 191 | } | 413 | echo $'\0' >> index.idx |
| 192 | fi | 414 | it "fails to verify the pack index and with desired output" && { |
| 415 | WITH_SNAPSHOT="$snapshot/index-failure" \ | ||
| 416 | expect_run $WITH_FAILURE "$exe_plumbing" pack verify index.idx | ||
| 417 | } | ||
| 418 | ) | ||
| 419 | ) | ||
| 193 | ) | 420 | ) |
| 194 | ) | 421 | ) |
| 195 | 422 | ||
| @@ -276,227 +503,7 @@ title "gix remote" · 80 unmodified lines | |||
| 276 | ) | 503 | ) |
| 277 | ) | 504 | ) |
| 278 | 505 | ||
| 279 | title "gix pack-index-from-data" | ||
| 280 | (when "running 'pack-index-from-data" | ||
| 281 | snapshot="$snapshot/pack-index-from-data" | ||
| 282 | PACK_FILE="$fixtures/packs/pack-11fdfa9e156ab73caae3b6da867192221f2089c2.pack" | ||
| 283 | (with "a valid and complete pack file" | ||
| 284 | (with "NO output directory specified" | ||
| 285 | (with "pack file passed as file" | ||
| 286 | it "generates an index into a sink and outputs pack and index information" && { | ||
| 287 | WITH_SNAPSHOT="$snapshot/no-output-dir-success" \ | ||
| 288 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-index-from-data -p "$PACK_FILE" | ||
| 289 | } | ||
| 290 | ) | ||
| 291 | (with "pack file passed from stdin" | ||
| 292 | it "generates an index into a sink and outputs pack and index information" && { | ||
| 293 | WITH_SNAPSHOT="$snapshot/no-output-dir-success" \ | ||
| 294 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-index-from-data < "$PACK_FILE" | ||
| 295 | } | ||
| 296 | if test "$kind" = "max"; then | ||
| 297 | (with "--format json" | ||
| 298 | it "generates the index into a sink and outputs information as JSON" && { | ||
| 299 | WITH_SNAPSHOT="$snapshot/no-output-dir-as-json-success" \ | ||
| 300 | expect_run $SUCCESSFULLY "$exe_plumbing" --format json pack-index-from-data < "$PACK_FILE" | ||
| 301 | } | ||
| 302 | ) | ||
| 303 | fi | ||
| 304 | ) | ||
| 305 | ) | ||
| 306 | (sandbox | ||
| 307 | (with "with an output directory specified" | ||
| 308 | it "generates an index and outputs information" && { | ||
| 309 | WITH_SNAPSHOT="$snapshot/output-dir-success" \ | ||
| 310 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-index-from-data -p "$PACK_FILE" "$PWD" | ||
| 311 | } | ||
| 312 | it "writes the index and pack into the directory (they have the same names, different suffixes)" && { | ||
| 313 | WITH_SNAPSHOT="$snapshot/output-dir-content" \ | ||
| 314 | expect_run $SUCCESSFULLY ls | ||
| 315 | } | ||
| 316 | ) | ||
| 317 | ) | ||
| 318 | ) | ||
| 319 | (with "'restore' iteration mode" | ||
| 320 | (sandbox | ||
| 321 | cp "${PACK_FILE}" . | ||
| 322 | PACK_FILE="${PACK_FILE##*/}" | ||
| 323 | "$jtt" mess-in-the-middle "${PACK_FILE}" | ||
| 324 | |||
| 325 | it "generates an index and outputs information (instead of failing)" && { | ||
| 326 | WITH_SNAPSHOT="$snapshot/output-dir-restore-success" \ | ||
| 327 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-index-from-data -i restore -p "$PACK_FILE" "$PWD" | ||
| 328 | } | ||
| 329 | 506 | ||
| 330 | if test "$kind" = "max"; then | ||
| 331 | (with "--format json and the very same output directory" | ||
| 332 | it "generates the index, overwriting existing files, and outputs information as JSON" && { | ||
| 333 | WITH_SNAPSHOT="$snapshot/output-dir-restore-as-json-success" \ | ||
| 334 | SNAPSHOT_FILTER=remove-paths \ | ||
| 335 | expect_run $SUCCESSFULLY "$exe_plumbing" --format json pack-index-from-data -i restore $PWD < "$PACK_FILE" | ||
| 336 | } | ||
| 337 | ) | ||
| 338 | fi | ||
| 339 | ) | ||
| 340 | ) | ||
| 341 | ) | ||
| 342 | title "gix pack-explode" | ||
| 343 | (when "running 'pack-explode" | ||
| 344 | snapshot="$snapshot/pack-explode" | ||
| 345 | PACK_FILE="$fixtures/packs/pack-11fdfa9e156ab73caae3b6da867192221f2089c2" | ||
| 346 | (with "no objects directory specified" | ||
| 347 | it "explodes the pack successfully and with desired output" && { | ||
| 348 | WITH_SNAPSHOT="$snapshot/to-sink-success" \ | ||
| 349 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-explode "${PACK_FILE}.idx" | ||
| 350 | } | ||
| 351 | |||
| 352 | (when "using the --delete-pack flag" | ||
| 353 | (sandbox | ||
| 354 | (with "a valid pack" | ||
| 355 | cp "${PACK_FILE}".idx "${PACK_FILE}".pack . | ||
| 356 | PACK_FILE="${PACK_FILE##*/}" | ||
| 357 | it "explodes the pack successfully and deletes the original pack and index" && { | ||
| 358 | WITH_SNAPSHOT="$snapshot/to-sink-delete-pack-success" \ | ||
| 359 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-explode --check skip-file-checksum --delete-pack "${PACK_FILE}.pack" | ||
| 360 | } | ||
| 361 | it "removes the original files" && { | ||
| 362 | expect_run $WITH_FAILURE test -e "${PACK_FILE}".pack | ||
| 363 | expect_run $WITH_FAILURE test -e "${PACK_FILE}".idx | ||
| 364 | } | ||
| 365 | ) | ||
| 366 | (with "a pack file that is invalid somewhere" | ||
| 367 | cp ${PACK_FILE}.idx ${PACK_FILE}.pack . | ||
| 368 | PACK_FILE="${PACK_FILE##*/}" | ||
| 369 | "$jtt" mess-in-the-middle "${PACK_FILE}".pack | ||
| 370 | |||
| 371 | (with "and all safety checks" | ||
| 372 | it "does not explode the file at all" && { | ||
| 373 | WITH_SNAPSHOT="$snapshot/broken-delete-pack-to-sink-failure" \ | ||
| 374 | expect_run $WITH_FAILURE "$exe_plumbing" pack-explode --sink-compress --check all --delete-pack "${PACK_FILE}.pack" | ||
| 375 | } | ||
| 376 | |||
| 377 | it "did not touch index or pack file" && { | ||
| 378 | expect_exists "${PACK_FILE}".pack | ||
| 379 | expect_exists "${PACK_FILE}".idx | ||
| 380 | } | ||
| 381 | ) | ||
| 382 | |||
| 383 | (with "and no safety checks at all (and an output directory)" | ||
| 384 | it "does explode the file" && { | ||
| 385 | WITH_SNAPSHOT="$snapshot/broken-delete-pack-to-sink-skip-checks-success" \ | ||
| 386 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-explode --verify --check skip-file-and-object-checksum-and-no-abort-on-decode \ | ||
| 387 | --delete-pack "${PACK_FILE}.pack" . | ||
| 388 | } | ||
| 389 | |||
| 390 | it "removes the original files" && { | ||
| 391 | expect_run $WITH_FAILURE test -e "${PACK_FILE}".pack | ||
| 392 | expect_run $WITH_FAILURE test -e "${PACK_FILE}".idx | ||
| 393 | } | ||
| 394 | |||
| 395 | (with_program tree | ||
| 396 | |||
| 397 | if test "$kind" = "small"; then | ||
| 398 | suffix=miniz-oxide | ||
| 399 | else | ||
| 400 | suffix=zlib-ng | ||
| 401 | fi | ||
| 402 | it "creates all pack objects, but the broken ones" && { | ||
| 403 | WITH_SNAPSHOT="$snapshot/broken-with-objects-dir-skip-checks-success-tree-$suffix" \ | ||
| 404 | expect_run $SUCCESSFULLY tree | ||
| 405 | } | ||
| 406 | ) | ||
| 407 | ) | ||
| 408 | ) | ||
| 409 | ) | ||
| 410 | ) | ||
| 411 | ) | ||
| 412 | (with "a non-existing directory specified" | ||
| 413 | it "fails with a helpful error message" && { | ||
| 414 | WITH_SNAPSHOT="$snapshot/missing-objects-dir-fail" \ | ||
| 415 | expect_run $WITH_FAILURE "$exe_plumbing" pack-explode -c skip-file-and-object-checksum "${PACK_FILE}.idx" does-not-exist | ||
| 416 | } | ||
| 417 | ) | ||
| 418 | (with "an existing directory specified" | ||
| 419 | (sandbox | ||
| 420 | it "succeeds" && { | ||
| 421 | WITH_SNAPSHOT="$snapshot/with-objects-dir-success" \ | ||
| 422 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-explode -c skip-file-and-object-checksum-and-no-abort-on-decode \ | ||
| 423 | "${PACK_FILE}.pack" . | ||
| 424 | } | ||
| 425 | |||
| 426 | (with_program tree | ||
| 427 | it "creates all pack objects" && { | ||
| 428 | WITH_SNAPSHOT="$snapshot/with-objects-dir-success-tree" \ | ||
| 429 | expect_run $SUCCESSFULLY tree | ||
| 430 | } | ||
| 431 | ) | ||
| 432 | ) | ||
| 433 | ) | ||
| 434 | ) | ||
| 435 | |||
| 436 | title "gix pack-verify" | ||
| 437 | (when "running 'pack-verify" | ||
| 438 | snapshot="$snapshot/pack-verify" | ||
| 439 | (with "a valid pack file" | ||
| 440 | PACK_FILE="$fixtures/packs/pack-11fdfa9e156ab73caae3b6da867192221f2089c2.pack" | ||
| 441 | it "verifies the pack successfully and with desired output" && { | ||
| 442 | WITH_SNAPSHOT="$snapshot/success" \ | ||
| 443 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-verify "$PACK_FILE" | ||
| 444 | } | ||
| 445 | ) | ||
| 446 | (with "a valid pack INDEX file" | ||
| 447 | PACK_INDEX_FILE="$fixtures/packs/pack-11fdfa9e156ab73caae3b6da867192221f2089c2.idx" | ||
| 448 | (with "no statistics" | ||
| 449 | it "verifies the pack index successfully and with desired output" && { | ||
| 450 | WITH_SNAPSHOT="$snapshot/index-success" \ | ||
| 451 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-verify "$PACK_INDEX_FILE" | ||
| 452 | } | ||
| 453 | ) | ||
| 454 | (with "statistics" | ||
| 455 | it "verifies the pack index successfully and with desired output" && { | ||
| 456 | WITH_SNAPSHOT="$snapshot/index-with-statistics-success" \ | ||
| 457 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-verify --statistics "$PACK_INDEX_FILE" | ||
| 458 | } | ||
| 459 | |||
| 460 | (with "and the less-memory algorithm" | ||
| 461 | it "verifies the pack index successfully and with desired output" && { | ||
| 462 | WITH_SNAPSHOT="$snapshot/index-with-statistics-success" \ | ||
| 463 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-verify --algorithm less-memory --statistics "$PACK_INDEX_FILE" | ||
| 464 | } | ||
| 465 | ) | ||
| 466 | ) | ||
| 467 | (with "decode" | ||
| 468 | it "verifies the pack index successfully and with desired output, and decodes all objects" && { | ||
| 469 | WITH_SNAPSHOT="$snapshot/index-success" \ | ||
| 470 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-verify --algorithm less-memory --decode "$PACK_INDEX_FILE" | ||
| 471 | } | ||
| 472 | ) | ||
| 473 | (with "re-encode" | ||
| 474 | it "verifies the pack index successfully and with desired output, and re-encodes all objects" && { | ||
| 475 | WITH_SNAPSHOT="$snapshot/index-success" \ | ||
| 476 | expect_run $SUCCESSFULLY "$exe_plumbing" pack-verify --algorithm less-time --re-encode "$PACK_INDEX_FILE" | ||
| 477 | } | ||
| 478 | ) | ||
| 479 | if test "$kind" = "max"; then | ||
| 480 | (with "statistics (JSON)" | ||
| 481 | it "verifies the pack index successfully and with desired output" && { | ||
| 482 | WITH_SNAPSHOT="$snapshot/index-with-statistics-json-success" \ | ||
| 483 | expect_run $SUCCESSFULLY "$exe_plumbing" --format json --threads 1 pack-verify --statistics "$PACK_INDEX_FILE" | ||
| 484 | } | ||
| 485 | ) | ||
| 486 | fi | ||
| 487 | ) | ||
| 488 | (sandbox | ||
| 489 | (with "an INvalid pack INDEX file" | ||
| 490 | PACK_INDEX_FILE="$fixtures/packs/pack-11fdfa9e156ab73caae3b6da867192221f2089c2.idx" | ||
| 491 | cp $PACK_INDEX_FILE index.idx | ||
| 492 | echo $'\0' >> index.idx | ||
| 493 | it "fails to verify the pack index and with desired output" && { | ||
| 494 | WITH_SNAPSHOT="$snapshot/index-failure" \ | ||
| 495 | expect_run $WITH_FAILURE "$exe_plumbing" pack-verify index.idx | ||
| 496 | } | ||
| 497 | ) | ||
| 498 | ) | ||
| 499 | ) | ||
| 500 | 507 | ||
| 501 | title "gix commitgraph" | 508 | title "gix commitgraph" |
| 502 | (when "running 'commitgraph'" | 509 | (when "running 'commitgraph'" |
| @@ -1,10 +0,0 @@ | |||
| 1 | error: The subcommand 'pack-receive' wasn't recognized | ||
| 2 | |||
| 3 | Did you mean 'pack-index-from-data' or 'pack-explode' or 'pack-verify' or 'pack-create'? | ||
| 4 | |||
| 5 | If you believe you received this message in error, try re-running with 'gix -- pack-receive' | ||
| 6 | |||
| 7 | USAGE: | ||
| 8 | gix [OPTIONS] <SUBCOMMAND> | ||
| 9 | |||
| 10 | For more information try --help | ||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -0,0 +1,6 @@ | |||
| 1 | error: Found argument 'receive' which wasn't expected, or isn't valid in this context | ||
| 2 | |||
| 3 | USAGE: | ||
| 4 | gix pack <SUBCOMMAND> | ||
| 5 | |||
| 6 | For more information try --help | ||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -0,0 +1,6 @@ | |||
| 1 | error: Found argument 'remote' which wasn't expected, or isn't valid in this context | ||
| 2 | |||
| 3 | USAGE: | ||
| 4 | gix [OPTIONS] <SUBCOMMAND> | ||
| 5 | |||
| 6 | For more information try --help | ||