History

'pack' with its own sub-commands (#289)

Sebastian Thiel committed 4 years ago

Commit fb64af41 parent 8677f7e38 files · +754 −721Browse files

Unified · Split

38 files
  1. src/plumbing/main.rs +196 −192
  2. src/plumbing/options.rs +207 −187
  3. tests/journey/gix.sh +339 −332
  4. tests/snapshots/plumbing/pack-receive/pack-receive-no-networking-in-small-failure +0 −10
  5. tests/snapshots/plumbing/pack/explode/broken-delete-pack-to-sink-failure +0 −0
  6. tests/snapshots/plumbing/pack/explode/broken-delete-pack-to-sink-skip-checks-success +0 −0
  7. tests/snapshots/plumbing/pack/explode/broken-with-objects-dir-skip-checks-success-tree-miniz-oxide +0 −0
  8. tests/snapshots/plumbing/pack/explode/broken-with-objects-dir-skip-checks-success-tree-zlib-ng +0 −0
  9. tests/snapshots/plumbing/pack/explode/missing-objects-dir-fail +0 −0
  10. tests/snapshots/plumbing/pack/explode/to-sink-delete-pack-success +0 −0
  11. tests/snapshots/plumbing/pack/explode/to-sink-success +0 −0
  12. tests/snapshots/plumbing/pack/explode/with-objects-dir-success +0 −0
  13. tests/snapshots/plumbing/pack/explode/with-objects-dir-success-tree +0 −0
  14. tests/snapshots/plumbing/pack/index-from-data/no-output-dir-as-json-success +0 −0
  15. tests/snapshots/plumbing/pack/index-from-data/no-output-dir-success +0 −0
  16. tests/snapshots/plumbing/pack/index-from-data/output-dir-content +0 −0
  17. tests/snapshots/plumbing/pack/index-from-data/output-dir-restore-as-json-success +0 −0
  18. tests/snapshots/plumbing/pack/index-from-data/output-dir-restore-success +0 −0
  19. tests/snapshots/plumbing/pack/index-from-data/output-dir-success +0 −0
  20. tests/snapshots/plumbing/pack/receive/file-v-any-no-output +0 −0
  21. tests/snapshots/plumbing/pack/receive/file-v-any-no-output-json +0 −0
  22. tests/snapshots/plumbing/pack/receive/file-v-any-no-output-non-existing-single-ref +0 −0
  23. tests/snapshots/plumbing/pack/receive/file-v-any-no-output-single-ref +0 −0
  24. tests/snapshots/plumbing/pack/receive/file-v-any-no-output-wanted-ref-p1 +0 −0
  25. tests/snapshots/plumbing/pack/receive/file-v-any-with-output +0 −0
  26. tests/snapshots/plumbing/pack/receive/ls-in-output-dir +0 −0
  27. tests/snapshots/plumbing/pack/receive/pack receive-no-networking-in-small-failure +6 −0
  28. tests/snapshots/plumbing/pack/receive/repo-refs/HEAD +0 −0
  29. tests/snapshots/plumbing/pack/receive/repo-refs/refs/heads/dev +0 −0
  30. tests/snapshots/plumbing/pack/receive/repo-refs/refs/heads/main +0 −0
  31. tests/snapshots/plumbing/pack/receive/repo-refs/refs/tags/annotated +0 −0
  32. tests/snapshots/plumbing/pack/receive/repo-refs/refs/tags/unannotated +0 −0
  33. tests/snapshots/plumbing/pack/verify/index-failure +0 −0
  34. tests/snapshots/plumbing/pack/verify/index-success +0 −0
  35. tests/snapshots/plumbing/pack/verify/index-with-statistics-json-success +0 −0
  36. tests/snapshots/plumbing/pack/verify/index-with-statistics-success +0 −0
  37. tests/snapshots/plumbing/pack/verify/success +0 −0
  38. tests/snapshots/plumbing/remote/ref-list/remote ref-list-no-networking-in-small-failure +6 −0
src/plumbing/main.rs+196−192
@@ -15,7 +15,7 @@ use gitoxide_core::pack::verify; · 14 unmodified lines
1515 #[cfg(any(feature = "gitoxide-core-async-client", feature = "gitoxide-core-blocking-client"))]
1616 use crate::plumbing::options::remote;
1717 use crate::{
18− plumbing::options::{commitgraph, Args, Subcommands},
18+ plumbing::options::{commitgraph, pack, Args, Subcommands},
1919 shared::pretty::prepare_and_run,
2020 };
2121
@@ -72,111 +72,215 @@ pub fn main() -> Result<()> { · 50 unmodified lines
7272 })?;
7373
7474 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
11597 } 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 {
133126 protocol,
134− &url,
127+ url,
135128 directory,
129+ refs,
136130 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(
163135 protocol,
164136 &url,
165137 directory,
166138 refs_directory,
167− refs.into_iter().map(|r| r.into()).collect(),
139+ refs.into_iter().map(|s| s.into()).collect(),
168140 git_features::progress::DoOrDiscard::from(progress),
169141 core::pack::receive::Context {
170142 thread_limit,
171143 format,
144+ out: std::io::stdout(),
172145 should_interrupt,
173− out,
174146 },
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"))]
179282 Subcommands::Remote(subcommands) => match subcommands {
283+ #[cfg(feature = "gitoxide-core-async-client")]
180284 remote::Subcommands::RefList { protocol, url } => {
181285 let (_handle, progress) =
182286 async_util::prepare(verbose, "remote-ref-list", Some(core::remote::refs::PROGRESS_RANGE));
@@ -192,9 +296,7 @@ pub fn main() -> Result<()> { · 9 unmodified lines
192296 );
193297 return futures_lite::future::block_on(fut);
194298 }
195− },
196− #[cfg(feature = "gitoxide-core-blocking-client")]
197− Subcommands::Remote(subcommands) => match subcommands {
299+ #[cfg(feature = "gitoxide-core-blocking-client")]
198300 remote::Subcommands::RefList { protocol, url } => prepare_and_run(
199301 "remote-ref-list",
200302 verbose,
@@ -215,104 +317,6 @@ pub fn main() -> Result<()> { · 14 unmodified lines
215317 },
216318 ),
217319 },
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(|_| ()),
316320 Subcommands::Commitgraph(subcommands) => match subcommands {
317321 commitgraph::Subcommands::Verify { path, statistics } => prepare_and_run(
318322 "commit-graph-verify",
src/plumbing/options.rs+207−187
@@ -1,5 +1,3 @@
1−use std::{ffi::OsString, path::PathBuf};
2−
31 use clap::AppSettings;
42 use gitoxide_core as core;
53
@@ -44,203 +42,225 @@ pub struct Args { · 38 unmodified lines
4442
4543 #[derive(Debug, clap::Parser)]
4644 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+}
5856
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;
7763
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>,
8672
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>,
9478
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,
9885
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,
11290
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>,
11897
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>,
123106
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,
129114
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>,
161118
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>,
227180
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.
230188 ///
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+ }
244264 }
245265
246266 ///
tests/journey/gix.sh+339−332
@@ -39,157 +39,384 @@ title "git-tempfile crate" · 38 unmodified lines
3939 )
4040 )
4141
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
4751
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
5690 )
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
68140 it "generates the correct output" && {
69141 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/
71143 }
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/
74171 }
75172 )
76− rm -Rf out
77173 )
174+ )
175+ (on_ci
78176 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+ )
84188 )
85189 fi
86190 )
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"
92209 }
93210 )
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"
99215 }
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
103235 }
104− rm -Rf out
105236 )
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+
106250 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"
111256 }
112257 )
113258 fi
114259 )
115260 )
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"
131281 }
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
148285 }
149286 )
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
159301 }
160302 )
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+ )
161329 )
162330 )
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− )
169331 )
170332 )
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
177351 }
178352 )
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"
182385 }
183386 )
184387 )
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+ )
185407 fi
186408 )
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+ )
193420 )
194421 )
195422
@@ -276,227 +503,7 @@ title "gix remote" · 80 unmodified lines
276503 )
277504 )
278505
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− }
329506
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−)
500507
501508 title "gix commitgraph"
502509 (when "running 'commitgraph'"
tests/snapshots/plumbing/pack-receive/pack-receive-no-networking-in-small-failure+0−10
@@ -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
tests/snapshots/plumbing/pack/explode/broken-delete-pack-to-sink-failurerenamed from tests/snapshots/plumbing/pack-explode/broken-delete-pack-to-sink-failure+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/explode/broken-delete-pack-to-sink-skip-checks-successrenamed from tests/snapshots/plumbing/pack-explode/broken-delete-pack-to-sink-skip-checks-success+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/explode/broken-with-objects-dir-skip-checks-success-tree-miniz-oxiderenamed from tests/snapshots/plumbing/pack-explode/broken-with-objects-dir-skip-checks-success-tree-miniz-oxide+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/explode/broken-with-objects-dir-skip-checks-success-tree-zlib-ngrenamed from tests/snapshots/plumbing/pack-explode/broken-with-objects-dir-skip-checks-success-tree-zlib-ng+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/explode/missing-objects-dir-failrenamed from tests/snapshots/plumbing/pack-explode/missing-objects-dir-fail+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/explode/to-sink-delete-pack-successrenamed from tests/snapshots/plumbing/pack-explode/to-sink-delete-pack-success+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/explode/to-sink-successrenamed from tests/snapshots/plumbing/pack-explode/to-sink-success+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/explode/with-objects-dir-successrenamed from tests/snapshots/plumbing/pack-explode/with-objects-dir-success+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/explode/with-objects-dir-success-treerenamed from tests/snapshots/plumbing/pack-explode/with-objects-dir-success-tree+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/index-from-data/no-output-dir-as-json-successrenamed from tests/snapshots/plumbing/pack-index-from-data/no-output-dir-as-json-success+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/index-from-data/no-output-dir-successrenamed from tests/snapshots/plumbing/pack-index-from-data/no-output-dir-success+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/index-from-data/output-dir-contentrenamed from tests/snapshots/plumbing/pack-index-from-data/output-dir-content+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/index-from-data/output-dir-restore-as-json-successrenamed from tests/snapshots/plumbing/pack-index-from-data/output-dir-restore-as-json-success+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/index-from-data/output-dir-restore-successrenamed from tests/snapshots/plumbing/pack-index-from-data/output-dir-restore-success+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/index-from-data/output-dir-successrenamed from tests/snapshots/plumbing/pack-index-from-data/output-dir-success+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/receive/file-v-any-no-outputrenamed from tests/snapshots/plumbing/pack-receive/file-v-any-no-output+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/receive/file-v-any-no-output-jsonrenamed from tests/snapshots/plumbing/pack-receive/file-v-any-no-output-json+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/receive/file-v-any-no-output-non-existing-single-refrenamed from tests/snapshots/plumbing/pack-receive/file-v-any-no-output-non-existing-single-ref+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/receive/file-v-any-no-output-single-refrenamed from tests/snapshots/plumbing/pack-receive/file-v-any-no-output-single-ref+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/receive/file-v-any-no-output-wanted-ref-p1renamed from tests/snapshots/plumbing/pack-receive/file-v-any-no-output-wanted-ref-p1+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/receive/file-v-any-with-outputrenamed from tests/snapshots/plumbing/pack-receive/file-v-any-with-output+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/receive/ls-in-output-dirrenamed from tests/snapshots/plumbing/pack-receive/ls-in-output-dir+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/receive/pack receive-no-networking-in-small-failure+6−0
@@ -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
tests/snapshots/plumbing/pack/receive/repo-refs/HEADrenamed from tests/snapshots/plumbing/pack-receive/repo-refs/HEAD+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/receive/repo-refs/refs/heads/devrenamed from tests/snapshots/plumbing/pack-receive/repo-refs/refs/heads/dev+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/receive/repo-refs/refs/heads/mainrenamed from tests/snapshots/plumbing/pack-receive/repo-refs/refs/heads/main+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/receive/repo-refs/refs/tags/annotatedrenamed from tests/snapshots/plumbing/pack-receive/repo-refs/refs/tags/annotated+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/receive/repo-refs/refs/tags/unannotatedrenamed from tests/snapshots/plumbing/pack-receive/repo-refs/refs/tags/unannotated+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/verify/index-failurerenamed from tests/snapshots/plumbing/pack-verify/index-failure+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/verify/index-successrenamed from tests/snapshots/plumbing/pack-verify/index-success+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/verify/index-with-statistics-json-successrenamed from tests/snapshots/plumbing/pack-verify/index-with-statistics-json-success+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/verify/index-with-statistics-successrenamed from tests/snapshots/plumbing/pack-verify/index-with-statistics-success+0−0

File renamed without changes.

tests/snapshots/plumbing/pack/verify/successrenamed from tests/snapshots/plumbing/pack-verify/success+0−0

File renamed without changes.

tests/snapshots/plumbing/remote/ref-list/remote ref-list-no-networking-in-small-failure+6−0
@@ -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