Unified · Split
| @@ -15,7 +15,7 @@ use gitoxide_core::pack::verify; · 14 unmodified lines | ||
| 15 | 15 | #[cfg(any(feature = "gitoxide-core-async-client", feature = "gitoxide-core-blocking-client"))] |
| 16 | 16 | use crate::plumbing::options::remote; |
| 17 | 17 | use crate::{ |
| 18 | − plumbing::options::{commitgraph, Args, Subcommands}, | |
| 18 | + plumbing::options::{commitgraph, pack, Args, Subcommands}, | |
| 19 | 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 | 74 | match cmd { |
| 75 | − Subcommands::PackCreate { | |
| 76 | − repository, | |
| 77 | − expansion, | |
| 78 | − thin, | |
| 79 | − statistics, | |
| 80 | − nondeterministic_count, | |
| 81 | − tips, | |
| 82 | − pack_cache_size_mb, | |
| 83 | − object_cache_size_mb, | |
| 84 | − output_directory, | |
| 85 | − } => { | |
| 86 | − let has_tips = !tips.is_empty(); | |
| 87 | − prepare_and_run( | |
| 88 | − "pack-create", | |
| 89 | − verbose, | |
| 90 | − progress, | |
| 91 | − progress_keep_open, | |
| 92 | − core::pack::create::PROGRESS_RANGE, | |
| 93 | − move |progress, out, _err| { | |
| 94 | − let input = if has_tips { | |
| 95 | − None | |
| 96 | − } else { | |
| 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 | |
| 75 | + Subcommands::Pack(subcommands) => match subcommands { | |
| 76 | + pack::Subcommands::Create { | |
| 77 | + repository, | |
| 78 | + expansion, | |
| 79 | + thin, | |
| 80 | + statistics, | |
| 81 | + nondeterministic_count, | |
| 82 | + tips, | |
| 83 | + pack_cache_size_mb, | |
| 84 | + object_cache_size_mb, | |
| 85 | + output_directory, | |
| 86 | + } => { | |
| 87 | + let has_tips = !tips.is_empty(); | |
| 88 | + prepare_and_run( | |
| 89 | + "pack-create", | |
| 90 | + verbose, | |
| 91 | + progress, | |
| 92 | + progress_keep_open, | |
| 93 | + core::pack::create::PROGRESS_RANGE, | |
| 94 | + move |progress, out, _err| { | |
| 95 | + let input = if has_tips { | |
| 96 | + None | |
| 115 | 97 | } else { |
| 116 | − core::pack::create::ObjectExpansion::None | |
| 117 | − }), | |
| 118 | − }; | |
| 119 | − core::pack::create(repository, tips, input, output_directory, progress, context) | |
| 120 | − }, | |
| 121 | − ) | |
| 122 | − } | |
| 123 | − #[cfg(feature = "gitoxide-core-async-client")] | |
| 124 | − Subcommands::PackReceive { | |
| 125 | − protocol, | |
| 126 | − url, | |
| 127 | − directory, | |
| 128 | − refs, | |
| 129 | − refs_directory, | |
| 130 | − } => { | |
| 131 | − let (_handle, progress) = async_util::prepare(verbose, "pack-receive", core::pack::receive::PROGRESS_RANGE); | |
| 132 | − let fut = core::pack::receive( | |
| 98 | + if atty::is(atty::Stream::Stdin) { | |
| 99 | + anyhow::bail!( | |
| 100 | + "Refusing to read from standard input as no path is given, but it's a terminal." | |
| 101 | + ) | |
| 102 | + } | |
| 103 | + Some(BufReader::new(stdin())) | |
| 104 | + }; | |
| 105 | + let repository = repository.unwrap_or_else(|| PathBuf::from(".")); | |
| 106 | + let context = core::pack::create::Context { | |
| 107 | + thread_limit, | |
| 108 | + thin, | |
| 109 | + nondeterministic_count, | |
| 110 | + pack_cache_size_in_bytes: pack_cache_size_mb.unwrap_or(0) * 1_000_000, | |
| 111 | + object_cache_size_in_bytes: object_cache_size_mb.unwrap_or(0) * 1_000_000, | |
| 112 | + statistics: if statistics { Some(format) } else { None }, | |
| 113 | + out, | |
| 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 | 126 | protocol, |
| 134 | − &url, | |
| 127 | + url, | |
| 135 | 128 | directory, |
| 129 | + refs, | |
| 136 | 130 | refs_directory, |
| 137 | − refs.into_iter().map(|s| s.into()).collect(), | |
| 138 | − git_features::progress::DoOrDiscard::from(progress), | |
| 139 | − core::pack::receive::Context { | |
| 140 | − thread_limit, | |
| 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( | |
| 131 | + } => { | |
| 132 | + let (_handle, progress) = | |
| 133 | + async_util::prepare(verbose, "pack-receive", core::pack::receive::PROGRESS_RANGE); | |
| 134 | + let fut = core::pack::receive( | |
| 163 | 135 | protocol, |
| 164 | 136 | &url, |
| 165 | 137 | directory, |
| 166 | 138 | refs_directory, |
| 167 | − refs.into_iter().map(|r| r.into()).collect(), | |
| 139 | + refs.into_iter().map(|s| s.into()).collect(), | |
| 168 | 140 | git_features::progress::DoOrDiscard::from(progress), |
| 169 | 141 | core::pack::receive::Context { |
| 170 | 142 | thread_limit, |
| 171 | 143 | format, |
| 144 | + out: std::io::stdout(), | |
| 172 | 145 | should_interrupt, |
| 173 | − out, | |
| 174 | 146 | }, |
| 175 | − ) | |
| 176 | − }, | |
| 177 | − ), | |
| 178 | − #[cfg(feature = "gitoxide-core-async-client")] | |
| 147 | + ); | |
| 148 | + return futures_lite::future::block_on(fut); | |
| 149 | + } | |
| 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 | 282 | Subcommands::Remote(subcommands) => match subcommands { |
| 283 | + #[cfg(feature = "gitoxide-core-async-client")] | |
| 180 | 284 | remote::Subcommands::RefList { protocol, url } => { |
| 181 | 285 | let (_handle, progress) = |
| 182 | 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 | 297 | return futures_lite::future::block_on(fut); |
| 194 | 298 | } |
| 195 | − }, | |
| 196 | − #[cfg(feature = "gitoxide-core-blocking-client")] | |
| 197 | − Subcommands::Remote(subcommands) => match subcommands { | |
| 299 | + #[cfg(feature = "gitoxide-core-blocking-client")] | |
| 198 | 300 | remote::Subcommands::RefList { protocol, url } => prepare_and_run( |
| 199 | 301 | "remote-ref-list", |
| 200 | 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 | 320 | Subcommands::Commitgraph(subcommands) => match subcommands { |
| 317 | 321 | commitgraph::Subcommands::Verify { path, statistics } => prepare_and_run( |
| 318 | 322 | "commit-graph-verify", |
| @@ -1,5 +1,3 @@ | ||
| 1 | −use std::{ffi::OsString, path::PathBuf}; | |
| 2 | − | |
| 3 | 1 | use clap::AppSettings; |
| 4 | 2 | use gitoxide_core as core; |
| 5 | 3 | |
| @@ -44,203 +42,225 @@ pub struct Args { · 38 unmodified lines | ||
| 44 | 42 | |
| 45 | 43 | #[derive(Debug, clap::Parser)] |
| 46 | 44 | pub enum Subcommands { |
| 47 | − #[clap(setting = AppSettings::DisableVersionFlag)] | |
| 48 | − PackCreate { | |
| 49 | − #[clap(long, short = 'r')] | |
| 50 | − /// the directory containing the '.git' repository from which objects should be read. | |
| 51 | − repository: Option<PathBuf>, | |
| 52 | − | |
| 53 | − #[clap(long, short = 'e', possible_values(core::pack::create::ObjectExpansion::variants()))] | |
| 54 | − /// the way objects are expanded. They differ in costs. | |
| 55 | − /// | |
| 56 | − /// Possible values are "none" and "tree-traversal". Default is "none". | |
| 57 | − expansion: Option<core::pack::create::ObjectExpansion>, | |
| 45 | + /// Subcommands for interacting with packs and their indices. | |
| 46 | + #[clap(subcommand)] | |
| 47 | + Pack(pack::Subcommands), | |
| 48 | + /// Subcommands for interacting with git remotes, e.g. git repositories hosted on servers. | |
| 49 | + #[clap(subcommand)] | |
| 50 | + #[cfg(any(feature = "gitoxide-core-async-client", feature = "gitoxide-core-blocking-client"))] | |
| 51 | + Remote(remote::Subcommands), | |
| 52 | + /// Subcommands for interacting with commitgraphs | |
| 53 | + #[clap(subcommand)] | |
| 54 | + Commitgraph(commitgraph::Subcommands), | |
| 55 | +} | |
| 58 | 56 | |
| 59 | − #[clap(long)] | |
| 60 | − /// if set, the counting phase may be accelerated using multithreading. | |
| 61 | − /// | |
| 62 | − /// On the flip side, however, one will loose deterministic counting results which affects the | |
| 63 | − /// way the resulting pack is structured. | |
| 64 | − nondeterministic_count: bool, | |
| 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>, | |
| 57 | +/// | |
| 58 | +pub mod pack { | |
| 59 | + use clap::AppSettings; | |
| 60 | + use gitoxide_core as core; | |
| 61 | + use std::ffi::OsString; | |
| 62 | + use std::path::PathBuf; | |
| 77 | 63 | |
| 78 | − #[clap(long)] | |
| 79 | − /// The size in megabytes for a cache to speed up accessing entire objects, bypassing object database access when hit. | |
| 80 | − /// It is shared among all threads, so 4 threads would use their own cache 1/4th of the size. | |
| 81 | − /// | |
| 82 | − /// This cache type is currently only effective when using the 'diff-tree' object expansion. | |
| 83 | − /// | |
| 84 | − /// If unset, no cache will be used. | |
| 85 | − object_cache_size_mb: Option<usize>, | |
| 64 | + #[derive(Debug, clap::Parser)] | |
| 65 | + pub enum Subcommands { | |
| 66 | + /// Create a new pack with a set of objects. | |
| 67 | + #[clap(setting = AppSettings::DisableVersionFlag)] | |
| 68 | + Create { | |
| 69 | + #[clap(long, short = 'r')] | |
| 70 | + /// the directory containing the '.git' repository from which objects should be read. | |
| 71 | + repository: Option<PathBuf>, | |
| 86 | 72 | |
| 87 | − #[clap(long)] | |
| 88 | − /// if set, delta-objects whose base object wouldn't be in the pack will not be recompressed as base object, but instead | |
| 89 | − /// refer to its base object using its object id. | |
| 90 | − /// | |
| 91 | − /// This allows for smaller packs but requires the receiver of the pack to resolve these ids before storing the pack. | |
| 92 | − /// Packs produced with this option enabled are only valid in transit, but not at rest. | |
| 93 | − thin: bool, | |
| 73 | + #[clap(long, short = 'e', possible_values(core::pack::create::ObjectExpansion::variants()))] | |
| 74 | + /// the way objects are expanded. They differ in costs. | |
| 75 | + /// | |
| 76 | + /// Possible values are "none" and "tree-traversal". Default is "none". | |
| 77 | + expansion: Option<core::pack::create::ObjectExpansion>, | |
| 94 | 78 | |
| 95 | − /// The directory into which to write the pack file. | |
| 96 | − #[clap(long, short = 'o')] | |
| 97 | − output_directory: Option<PathBuf>, | |
| 79 | + #[clap(long)] | |
| 80 | + /// if set, the counting phase may be accelerated using multithreading. | |
| 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 | |
| 100 | − /// or as branch names. | |
| 101 | − /// | |
| 102 | − /// If empty, we expect to read objects on stdin and default to 'none' as expansion mode. | |
| 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>, | |
| 86 | + #[clap(long, short = 's')] | |
| 87 | + /// If set statistical information will be presented to inform about pack creation details. | |
| 88 | + /// It's a form of instrumentation for developers to help improve pack generation. | |
| 89 | + statistics: bool, | |
| 112 | 90 | |
| 113 | − /// the directory into which to write references. Existing files will be overwritten. | |
| 114 | − /// | |
| 115 | − /// Note that the directory will be created if needed. | |
| 116 | − #[clap(long, short = 'd')] | |
| 117 | − refs_directory: Option<PathBuf>, | |
| 91 | + #[clap(long)] | |
| 92 | + /// The size in megabytes for a cache to speed up pack access for packs with long delta chains. | |
| 93 | + /// It is shared among all threads, so 4 threads would use their own cache 1/4th of the size. | |
| 94 | + /// | |
| 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. | |
| 120 | − /// | |
| 121 | − /// See here for a list of supported URLs: <https://www.git-scm.com/docs/git-clone#_git_urls> | |
| 122 | − url: String, | |
| 98 | + #[clap(long)] | |
| 99 | + /// The size in megabytes for a cache to speed up accessing entire objects, bypassing object database access when hit. | |
| 100 | + /// It is shared among all threads, so 4 threads would use their own cache 1/4th of the size. | |
| 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. | |
| 125 | − /// | |
| 126 | − /// Note that this requires a reasonably modern git server. | |
| 127 | − #[clap(long = "reference", short = 'r')] | |
| 128 | − refs: Vec<String>, | |
| 107 | + #[clap(long)] | |
| 108 | + /// if set, delta-objects whose base object wouldn't be in the pack will not be recompressed as base object, but instead | |
| 109 | + /// refer to its base object using its object id. | |
| 110 | + /// | |
| 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. | |
| 131 | − /// | |
| 132 | − /// If unset, they will be discarded. | |
| 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>, | |
| 115 | + /// The directory into which to write the pack file. | |
| 116 | + #[clap(long, short = 'o')] | |
| 117 | + output_directory: Option<PathBuf>, | |
| 161 | 118 | |
| 162 | − /// The folder into which to place the pack and the generated index file | |
| 163 | − /// | |
| 164 | − /// If unset, only informational output will be provided to standard output. | |
| 165 | − #[clap(parse(from_os_str))] | |
| 166 | − directory: Option<PathBuf>, | |
| 167 | − }, | |
| 168 | − /// Verify the integrity of a pack or index file | |
| 169 | − #[clap(setting = AppSettings::DisableVersionFlag)] | |
| 170 | − PackExplode { | |
| 171 | − #[clap(long)] | |
| 172 | − /// Read written objects back and assert they match their source. Fail the operation otherwise. | |
| 173 | − /// | |
| 174 | − /// Only relevant if an object directory is set. | |
| 175 | − verify: bool, | |
| 176 | − | |
| 177 | − /// delete the pack and index file after the operation is successful | |
| 178 | − #[clap(long)] | |
| 179 | − delete_pack: bool, | |
| 180 | − | |
| 181 | − /// The amount of checks to run | |
| 182 | − #[clap( | |
| 183 | − long, | |
| 184 | − short = 'c', | |
| 185 | − default_value = "all", | |
| 186 | − possible_values(core::pack::explode::SafetyCheck::variants()) | |
| 187 | − )] | |
| 188 | − check: core::pack::explode::SafetyCheck, | |
| 189 | − | |
| 190 | − /// Compress bytes even when using the sink, i.e. no object directory is specified | |
| 191 | − /// | |
| 192 | − /// This helps to determine overhead related to compression. If unset, the sink will | |
| 193 | − /// only create hashes from bytes, which is usually limited by the speed at which input | |
| 194 | − /// can be obtained. | |
| 195 | − #[clap(long)] | |
| 196 | − sink_compress: bool, | |
| 197 | − | |
| 198 | − /// The '.pack' or '.idx' file to explode into loose objects | |
| 199 | − #[clap(parse(from_os_str))] | |
| 200 | − pack_path: PathBuf, | |
| 201 | − | |
| 202 | − /// The path into which all objects should be written. Commonly '.git/objects' | |
| 203 | − #[clap(parse(from_os_str))] | |
| 204 | − object_path: Option<PathBuf>, | |
| 205 | − }, | |
| 206 | − /// Verify the integrity of a pack or index file | |
| 207 | − #[clap(setting = AppSettings::DisableVersionFlag)] | |
| 208 | − PackVerify { | |
| 209 | − /// output statistical information about the pack | |
| 210 | − #[clap(long, short = 's')] | |
| 211 | − statistics: bool, | |
| 212 | − /// The algorithm used to verify the pack. They differ in costs. | |
| 213 | − #[clap( | |
| 214 | − long, | |
| 215 | − short = 'a', | |
| 216 | − default_value = "less-time", | |
| 217 | − possible_values(core::pack::verify::Algorithm::variants()) | |
| 218 | − )] | |
| 219 | − algorithm: core::pack::verify::Algorithm, | |
| 220 | − | |
| 221 | − #[clap(long, conflicts_with("re-encode"))] | |
| 222 | − /// Decode and parse tags, commits and trees to validate their correctness beyond hashing correctly. | |
| 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, | |
| 119 | + /// The tips from which to start the commit graph iteration, either as fully qualified commit hashes | |
| 120 | + /// or as branch names. | |
| 121 | + /// | |
| 122 | + /// If empty, we expect to read objects on stdin and default to 'none' as expansion mode. | |
| 123 | + /// Otherwise the expansion mode is 'tree-traversal' by default. | |
| 124 | + tips: Vec<OsString>, | |
| 125 | + }, | |
| 126 | + /// Use the git-protocol to receive a pack, emulating a clone. | |
| 127 | + #[clap(setting = AppSettings::DisableVersionFlag)] | |
| 128 | + #[cfg(any(feature = "gitoxide-core-async-client", feature = "gitoxide-core-blocking-client"))] | |
| 129 | + Receive { | |
| 130 | + /// The protocol version to use. Valid values are 1 and 2 | |
| 131 | + #[clap(long, short = 'p')] | |
| 132 | + protocol: Option<core::net::Protocol>, | |
| 133 | + | |
| 134 | + /// the directory into which to write references. Existing files will be overwritten. | |
| 135 | + /// | |
| 136 | + /// Note that the directory will be created if needed. | |
| 137 | + #[clap(long, short = 'd')] | |
| 138 | + refs_directory: Option<PathBuf>, | |
| 139 | + | |
| 140 | + /// The URLs or path from which to receive the pack. | |
| 141 | + /// | |
| 142 | + /// See here for a list of supported URLs: <https://www.git-scm.com/docs/git-clone#_git_urls> | |
| 143 | + url: String, | |
| 144 | + | |
| 145 | + /// If set once or more times, these references will be fetched instead of all advertised ones. | |
| 146 | + /// | |
| 147 | + /// Note that this requires a reasonably modern git server. | |
| 148 | + #[clap(long = "reference", short = 'r')] | |
| 149 | + refs: Vec<String>, | |
| 150 | + | |
| 151 | + /// The directory into which to write the received pack and index. | |
| 152 | + /// | |
| 153 | + /// If unset, they will be discarded. | |
| 154 | + directory: Option<PathBuf>, | |
| 155 | + }, | |
| 156 | + /// create a pack index from a pack data file. | |
| 157 | + #[clap(setting = AppSettings::DisableVersionFlag)] | |
| 158 | + IndexFromData { | |
| 159 | + /// Specify how to iterate the pack, defaults to 'verify' | |
| 160 | + /// | |
| 161 | + /// Valid values are | |
| 162 | + /// | |
| 163 | + /// **as-is** do not do anything and expect the pack file to be valid as per the trailing hash, | |
| 164 | + /// **verify** the input ourselves and validate that it matches with the hash provided in the pack, | |
| 165 | + /// **restore** hash the input ourselves and ignore failing entries, instead finish the pack with the hash we computed | |
| 166 | + /// to keep as many objects as possible. | |
| 167 | + #[clap( | |
| 168 | + long, | |
| 169 | + short = 'i', | |
| 170 | + default_value = "verify", | |
| 171 | + possible_values(core::pack::index::IterationMode::variants()) | |
| 172 | + )] | |
| 173 | + iteration_mode: core::pack::index::IterationMode, | |
| 174 | + | |
| 175 | + /// Path to the pack file to read (with .pack extension). | |
| 176 | + /// | |
| 177 | + /// If unset, the pack file is expected on stdin. | |
| 178 | + #[clap(long, short = 'p')] | |
| 179 | + pack_path: Option<PathBuf>, | |
| 227 | 180 | |
| 228 | − #[clap(long)] | |
| 229 | − /// Decode and parse tags, commits and trees to validate their correctness, and re-encode them. | |
| 181 | + /// The folder into which to place the pack and the generated index file | |
| 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. | |
| 232 | − /// Encoding an object after decoding it should yield exactly the same bytes. | |
| 233 | − /// This will reduce overall performance even more, as re-encoding requires to transform zero-copy objects into | |
| 234 | − /// owned objects, causing plenty of allocation to occour. | |
| 235 | − re_encode: bool, | |
| 236 | − | |
| 237 | − /// The '.pack' or '.idx' file whose checksum to validate. | |
| 238 | − #[clap(parse(from_os_str))] | |
| 239 | − path: PathBuf, | |
| 240 | − }, | |
| 241 | − /// Subcommands for interacting with commitgraphs | |
| 242 | − #[clap(subcommand)] | |
| 243 | − Commitgraph(commitgraph::Subcommands), | |
| 189 | + /// Note that this effectively removes delta compression for an average compression of 2x, creating one file per object in the process. | |
| 190 | + /// Thus this should only be done to dissolve small packs after a fetch. | |
| 191 | + #[clap(setting = AppSettings::DisableVersionFlag)] | |
| 192 | + Explode { | |
| 193 | + #[clap(long)] | |
| 194 | + /// Read written objects back and assert they match their source. Fail the operation otherwise. | |
| 195 | + /// | |
| 196 | + /// Only relevant if an object directory is set. | |
| 197 | + verify: bool, | |
| 198 | + | |
| 199 | + /// delete the pack and index file after the operation is successful | |
| 200 | + #[clap(long)] | |
| 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" | |
| 43 | −(when "running 'pack-receive'" | |
| 44 | − snapshot="$snapshot/pack-receive" | |
| 45 | − (small-repo-in-sandbox | |
| 46 | − if [[ "$kind" != 'small' ]]; then | |
| 42 | +title "gix pack" | |
| 43 | +(when "running 'pack'" | |
| 44 | + snapshot="$snapshot/pack" | |
| 45 | + | |
| 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 | |
| 49 | − (with "file:// protocol" | |
| 50 | − (with "version 1" | |
| 51 | − (with "NO output directory" | |
| 52 | − it "generates the correct output" && { | |
| 53 | − WITH_SNAPSHOT="$snapshot/file-v-any-no-output" \ | |
| 54 | − expect_run $SUCCESSFULLY "$exe_plumbing" pack-receive -p 1 .git | |
| 55 | − } | |
| 52 | + if [[ "$kind" != 'async' ]]; then | |
| 53 | + (with "file:// protocol" | |
| 54 | + (with "version 1" | |
| 55 | + (with "NO output directory" | |
| 56 | + it "generates the correct output" && { | |
| 57 | + WITH_SNAPSHOT="$snapshot/file-v-any-no-output" \ | |
| 58 | + expect_run $SUCCESSFULLY "$exe_plumbing" pack receive -p 1 .git | |
| 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" | |
| 58 | − mkdir out | |
| 59 | − it "generates the correct output" && { | |
| 60 | − WITH_SNAPSHOT="$snapshot/file-v-any-with-output" \ | |
| 61 | − expect_run $SUCCESSFULLY "$exe_plumbing" pack-receive -p 1 .git out/ | |
| 62 | − } | |
| 63 | − it "creates an index and a pack in the output directory" && { | |
| 64 | − WITH_SNAPSHOT="$snapshot/ls-in-output-dir" \ | |
| 65 | − expect_run $SUCCESSFULLY ls out/ | |
| 66 | − } | |
| 67 | − (with "--write-refs set" | |
| 91 | + (with "version 2" | |
| 92 | + (with "NO output directory" | |
| 93 | + it "generates the correct output" && { | |
| 94 | + WITH_SNAPSHOT="$snapshot/file-v-any-no-output" \ | |
| 95 | + expect_run $SUCCESSFULLY "$exe_plumbing" pack receive -p 2 .git | |
| 96 | + } | |
| 97 | + ) | |
| 98 | + (with "output directory" | |
| 99 | + mkdir out/ | |
| 100 | + it "generates the correct output" && { | |
| 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 | 140 | it "generates the correct output" && { |
| 69 | 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" && { | |
| 73 | − expect_snapshot "$snapshot/repo-refs" out/all-refs | |
| 144 | + ) | |
| 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 | 176 | if test "$kind" = "max"; then |
| 79 | − (with "--format json" | |
| 80 | − it "generates the correct output in JSON format" && { | |
| 81 | − WITH_SNAPSHOT="$snapshot/file-v-any-no-output-json" \ | |
| 82 | − expect_run $SUCCESSFULLY "$exe_plumbing" --format json pack-receive --protocol 1 .git | |
| 83 | − } | |
| 177 | + (with "https:// protocol" | |
| 178 | + (with "version 1" | |
| 179 | + it "works" && { | |
| 180 | + expect_run $SUCCESSFULLY "$exe_plumbing" pack receive -p 1 https://github.com/byron/gitoxide | |
| 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 | 189 | fi |
| 86 | 190 | ) |
| 87 | − (with "version 2" | |
| 88 | − (with "NO output directory" | |
| 89 | − it "generates the correct output" && { | |
| 90 | − WITH_SNAPSHOT="$snapshot/file-v-any-no-output" \ | |
| 91 | − expect_run $SUCCESSFULLY "$exe_plumbing" pack-receive -p 2 .git | |
| 191 | + elif [[ "$kind" = "small" ]]; then | |
| 192 | + it "fails as the CLI doesn't have networking in 'small' mode" && { | |
| 193 | + WITH_SNAPSHOT="$snapshot/pack receive-no-networking-in-small-failure" \ | |
| 194 | + expect_run 2 "$exe_plumbing" pack receive -p 1 .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" | |
| 95 | − mkdir out/ | |
| 96 | − it "generates the correct output" && { | |
| 97 | − WITH_SNAPSHOT="$snapshot/file-v-any-with-output" \ | |
| 98 | − expect_run $SUCCESSFULLY "$exe_plumbing" pack-receive .git out/ | |
| 211 | + (with "pack file passed from stdin" | |
| 212 | + it "generates an index into a sink and outputs pack and index information" && { | |
| 213 | + WITH_SNAPSHOT="$snapshot/no-output-dir-success" \ | |
| 214 | + expect_run $SUCCESSFULLY "$exe_plumbing" pack index-from-data < "$PACK_FILE" | |
| 99 | 215 | } |
| 100 | − it "creates an index and a pack in the output directory" && { | |
| 101 | − WITH_SNAPSHOT="$snapshot/ls-in-output-dir" \ | |
| 102 | − expect_run $SUCCESSFULLY ls out/ | |
| 216 | + if test "$kind" = "max"; then | |
| 217 | + (with "--format json" | |
| 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 | 250 | if test "$kind" = "max"; then |
| 107 | − (with "--format json" | |
| 108 | − it "generates the correct output in JSON format" && { | |
| 109 | − WITH_SNAPSHOT="$snapshot/file-v-any-no-output-json" \ | |
| 110 | − expect_run $SUCCESSFULLY "$exe_plumbing" --format json pack-receive --protocol 2 .git | |
| 251 | + (with "--format json and the very same output directory" | |
| 252 | + it "generates the index, overwriting existing files, and outputs information as JSON" && { | |
| 253 | + WITH_SNAPSHOT="$snapshot/output-dir-restore-as-json-success" \ | |
| 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 | 258 | fi |
| 114 | 259 | ) |
| 115 | 260 | ) |
| 116 | − fi | |
| 117 | − (with "git:// protocol" | |
| 118 | − launch-git-daemon | |
| 119 | − (with "version 1" | |
| 120 | − (with "NO output directory" | |
| 121 | − (with "no wanted refs" | |
| 122 | − it "generates the correct output" && { | |
| 123 | − WITH_SNAPSHOT="$snapshot/file-v-any-no-output" \ | |
| 124 | − expect_run $SUCCESSFULLY "$exe_plumbing" pack-receive -p 1 git://localhost/ | |
| 125 | − } | |
| 126 | − ) | |
| 127 | − (with "wanted refs" | |
| 128 | − it "generates the correct output" && { | |
| 129 | − WITH_SNAPSHOT="$snapshot/file-v-any-no-output-wanted-ref-p1" \ | |
| 130 | − expect_run $WITH_FAILURE "$exe_plumbing" pack-receive -p 1 git://localhost/ -r =refs/heads/main | |
| 261 | + ) | |
| 262 | + | |
| 263 | + title "gix pack explode" | |
| 264 | + (with "the 'explode' sub-command" | |
| 265 | + snapshot="$snapshot/explode" | |
| 266 | + PACK_FILE="$fixtures/packs/pack-11fdfa9e156ab73caae3b6da867192221f2089c2" | |
| 267 | + (with "no objects directory specified" | |
| 268 | + it "explodes the pack successfully and with desired output" && { | |
| 269 | + WITH_SNAPSHOT="$snapshot/to-sink-success" \ | |
| 270 | + expect_run $SUCCESSFULLY "$exe_plumbing" pack explode "${PACK_FILE}.idx" | |
| 271 | + } | |
| 272 | + | |
| 273 | + (when "using the --delete-pack flag" | |
| 274 | + (sandbox | |
| 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 | − ) | |
| 133 | − ) | |
| 134 | − (with "output directory" | |
| 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/ | |
| 282 | + it "removes the original files" && { | |
| 283 | + expect_run $WITH_FAILURE test -e "${PACK_FILE}".pack | |
| 284 | + expect_run $WITH_FAILURE test -e "${PACK_FILE}".idx | |
| 148 | 285 | } |
| 149 | 286 | ) |
| 150 | − (with "wanted refs" | |
| 151 | − it "generates the correct output" && { | |
| 152 | − WITH_SNAPSHOT="$snapshot/file-v-any-no-output-single-ref" \ | |
| 153 | − expect_run $SUCCESSFULLY "$exe_plumbing" pack-receive -p 2 git://localhost/ -r refs/heads/main | |
| 154 | − } | |
| 155 | − (when "ref does not exist" | |
| 156 | − it "fails with a detailed error message including what the server said" && { | |
| 157 | − WITH_SNAPSHOT="$snapshot/file-v-any-no-output-non-existing-single-ref" \ | |
| 158 | − expect_run $WITH_FAILURE "$exe_plumbing" pack-receive -p 2 git://localhost/ -r refs/heads/does-not-exist | |
| 287 | + (with "a pack file that is invalid somewhere" | |
| 288 | + cp ${PACK_FILE}.idx ${PACK_FILE}.pack . | |
| 289 | + PACK_FILE="${PACK_FILE##*/}" | |
| 290 | + "$jtt" mess-in-the-middle "${PACK_FILE}".pack | |
| 291 | + | |
| 292 | + (with "and all safety checks" | |
| 293 | + it "does not explode the file at all" && { | |
| 294 | + WITH_SNAPSHOT="$snapshot/broken-delete-pack-to-sink-failure" \ | |
| 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 | |
| 172 | − if test "$kind" = "max"; then | |
| 173 | − (with "https:// protocol" | |
| 174 | − (with "version 1" | |
| 175 | − it "works" && { | |
| 176 | − expect_run $SUCCESSFULLY "$exe_plumbing" pack-receive -p 1 https://github.com/byron/gitoxide | |
| 333 | + (with "a non-existing directory specified" | |
| 334 | + it "fails with a helpful error message" && { | |
| 335 | + WITH_SNAPSHOT="$snapshot/missing-objects-dir-fail" \ | |
| 336 | + expect_run $WITH_FAILURE "$exe_plumbing" pack explode -c skip-file-and-object-checksum "${PACK_FILE}.idx" does-not-exist | |
| 337 | + } | |
| 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" | |
| 180 | − it "works" && { | |
| 181 | − expect_run $SUCCESSFULLY "$exe_plumbing" pack-receive -p 2 https://github.com/byron/gitoxide | |
| 353 | + ) | |
| 354 | + ) | |
| 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 | 407 | fi |
| 186 | 408 | ) |
| 187 | − elif [[ "$kind" = "small" ]]; then | |
| 188 | − it "fails as the CLI doesn't have networking in 'small' mode" && { | |
| 189 | − WITH_SNAPSHOT="$snapshot/pack-receive-no-networking-in-small-failure" \ | |
| 190 | − expect_run 2 "$exe_plumbing" pack-receive -p 1 .git | |
| 191 | − } | |
| 192 | − fi | |
| 409 | + (sandbox | |
| 410 | + (with "an INvalid pack INDEX file" | |
| 411 | + PACK_INDEX_FILE="$fixtures/packs/pack-11fdfa9e156ab73caae3b6da867192221f2089c2.idx" | |
| 412 | + cp $PACK_INDEX_FILE index.idx | |
| 413 | + echo $'\0' >> index.idx | |
| 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 | 508 | title "gix commitgraph" |
| 502 | 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 | |