History

A very first version of `gix progress show` (#450)

Sebastian Thiel committed 4 years ago

Commit 92e082a1 parent 8d17dc69 files · +756 −679Browse files

Unified · Split

9 files
  1. Cargo.lock +7 −0
  2. Cargo.toml +3 −0
  3. README.md +4 −0
  4. src/plumbing/main.rs +7 −2
  5. src/plumbing/mod.rs +4 −0
  6. src/plumbing/options.rs +0 −677
  7. src/plumbing/options/free.rs +368 −0
  8. src/plumbing/options/mod.rs +319 −0
  9. src/plumbing/progress.rs +44 −0
Cargo.lock+7−0
@@ -1835,6 +1835,7 @@ dependencies = [ · 1834 unmodified lines
18351835 "git-repository",
18361836 "git-transport",
18371837 "gitoxide-core",
1838+ "owo-colors",
18381839 "prodash",
18391840 ]
18401841
@@ -2380,6 +2381,12 @@ dependencies = [ · 539 unmodified lines
23802381 "winapi",
23812382 ]
23822383
2384+[[package]]
2385+name = "owo-colors"
2386+version = "3.5.0"
2387+source = "registry+https://github.com/rust-lang/crates.io-index"
2388+checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
2389+
23832390 [[package]]
23842391 name = "parking"
23852392 version = "2.0.0"
Cargo.toml+3−0
@@ -92,6 +92,9 @@ env_logger = { version = "0.9.0", default-features = false } · 91 unmodified lines
9292 crosstermion = { version = "0.10.1", optional = true, default-features = false }
9393 futures-lite = { version = "1.12.0", optional = true, default-features = false, features = ["std"] }
9494
95+# for show-progress
96+owo-colors = "3.5.0"
97+
9598 document-features = { version = "0.2.0", optional = true }
9699
97100 [profile.dev.package]
README.md+4−0
@@ -27,6 +27,10 @@ Please see _'Development Status'_ for a listing of all crates and their capabili · 26 unmodified lines
2727 * Based on the [git-hours] algorithm.
2828 * See the [discussion][git-hours-discussion] for some performance data.
2929 * **the `gix` program** _(plumbing)_ - lower level commands for use in automation
30+ * **progress**
31+ * [x] **show** - provide an overview of what works and what doesn't from the perspective of the git configuration.
32+ This is likely to change a lot over time depending on actual needs, but maybe useful for you to see
33+ if particular git-configuration is picked up and where it deviates.
3034 * **config** - list the complete git configuration in human-readable form and optionally filter sections by name.
3135 * **exclude**
3236 * [x] **query** - check if path specs are excluded via gits exclusion rules like `.gitignore`.
src/plumbing/main.rs+7−2
@@ -14,8 +14,12 @@ use gitoxide_core as core; · 13 unmodified lines
1414 use gitoxide_core::pack::verify;
1515
1616 use crate::{
17− plumbing::options::{
18− commit, config, credential, exclude, free, mailmap, odb, remote, revision, tree, Args, Subcommands,
17+ plumbing::{
18+ options::{
19+ commit, config, credential, exclude, free, mailmap, odb, progress, remote, revision, tree, Args,
20+ Subcommands,
21+ },
22+ show_progress,
1923 },
2024 shared::pretty::prepare_and_run,
2125 };
@@ -111,6 +115,7 @@ pub fn main() -> Result<()> { · 89 unmodified lines
111115 })?;
112116
113117 match cmd {
118+ Subcommands::Progress(progress::Subcommands::Show) => show_progress(),
114119 Subcommands::Credential(cmd) => core::repository::credential(
115120 repository(Mode::StrictWithGitInstallConfig)?,
116121 match cmd {
src/plumbing/mod.rs+4−0
@@ -1,4 +1,8 @@
11 mod main;
22 pub use main::main;
33
4+#[path = "progress.rs"]
5+mod progress_impl;
6+pub use progress_impl::show_progress;
7+
48 mod options;
src/plumbing/options.rs+0−677
@@ -1,677 +0,0 @@
1−use std::path::PathBuf;
2−
3−use git_repository as git;
4−use git_repository::bstr::BString;
5−use gitoxide_core as core;
6−
7−#[derive(Debug, clap::Parser)]
8−#[clap(name = "gix-plumbing", about = "The git underworld", version = clap::crate_version!())]
9−#[clap(subcommand_required = true)]
10−#[clap(arg_required_else_help = true)]
11−pub struct Args {
12− /// The repository to access.
13− #[clap(short = 'r', long, default_value = ".")]
14− pub repository: PathBuf,
15−
16− /// Add these values to the configuration in the form of `key=value` or `key`.
17− ///
18− /// For example, if `key` is `core.abbrev`, set configuration like `[core] abbrev = key`,
19− /// or `remote.origin.url = foo` to set `[remote "origin"] url = foo`.
20− #[clap(long, short = 'c', parse(try_from_os_str = git::env::os_str_to_bstring))]
21− pub config: Vec<BString>,
22−
23− #[clap(long, short = 't')]
24− /// The amount of threads to use for some operations.
25− ///
26− /// If unset, or the value is 0, there is no limit and all logical cores can be used.
27− pub threads: Option<usize>,
28−
29− /// Display verbose messages and progress information
30− #[clap(long, short = 'v')]
31− pub verbose: bool,
32−
33− /// Bring up a terminal user interface displaying progress visually
34− #[cfg(feature = "prodash-render-tui")]
35− #[clap(long, conflicts_with("verbose"))]
36− pub progress: bool,
37−
38− /// The progress TUI will stay up even though the work is already completed.
39− ///
40− /// Use this to be able to read progress messages or additional information visible in the TUI log pane.
41− #[cfg(feature = "prodash-render-tui")]
42− #[clap(long, conflicts_with("verbose"), requires("progress"))]
43− pub progress_keep_open: bool,
44−
45− /// Determine the format to use when outputting statistics.
46− #[clap(
47− long,
48− short = 'f',
49− default_value = "human",
50− possible_values(core::OutputFormat::variants())
51− )]
52− pub format: core::OutputFormat,
53−
54− /// The object format to assume when reading files that don't inherently know about it, or when writing files.
55− #[clap(long, default_value_t = git_repository::hash::Kind::default(), possible_values(&["SHA1"]))]
56− pub object_hash: git_repository::hash::Kind,
57−
58− #[clap(subcommand)]
59− pub cmd: Subcommands,
60−}
61−
62−#[derive(Debug, clap::Subcommand)]
63−pub enum Subcommands {
64− /// Interact with the object database.
65− #[clap(subcommand)]
66− Odb(odb::Subcommands),
67− /// Interact with tree objects.
68− #[clap(subcommand)]
69− Tree(tree::Subcommands),
70− /// Interact with commit objects.
71− #[clap(subcommand)]
72− Commit(commit::Subcommands),
73− /// Verify the integrity of the entire repository
74− Verify {
75− #[clap(flatten)]
76− args: free::pack::VerifyOptions,
77− },
78− /// Query and obtain information about revisions.
79− #[clap(subcommand)]
80− Revision(revision::Subcommands),
81− /// A program just like `git credential`.
82− #[clap(subcommand)]
83− Credential(credential::Subcommands),
84− /// Interact with the mailmap.
85− #[clap(subcommand)]
86− Mailmap(mailmap::Subcommands),
87− /// Interact with the remote hosts.
88− Remote(remote::Platform),
89− /// Interact with the exclude files like .gitignore.
90− #[clap(subcommand)]
91− Exclude(exclude::Subcommands),
92− Config(config::Platform),
93− /// Subcommands that need no git repository to run.
94− #[clap(subcommand)]
95− Free(free::Subcommands),
96−}
97−
98−pub mod config {
99− /// Print all entries in a configuration file or access other sub-commands
100− #[derive(Debug, clap::Parser)]
101− #[clap(subcommand_required(false))]
102− pub struct Platform {
103− /// The filter terms to limit the output to matching sections and subsections only.
104− ///
105− /// Typical filters are `branch` or `remote.origin` or `remote.or*` - git-style globs are supported
106− /// and comparisons are case-insensitive.
107− pub filter: Vec<String>,
108− }
109−}
110−
111−pub mod remote {
112− use git_repository as git;
113−
114− #[derive(Debug, clap::Parser)]
115− pub struct Platform {
116− /// The name of the remote to connect to.
117− ///
118− /// If unset, the current branch will determine the remote.
119− #[clap(long, short = 'n')]
120− pub name: Option<String>,
121−
122− /// Connect directly to the given URL, forgoing any configuration from the repository.
123− #[clap(long, short = 'u', conflicts_with("name"), parse(try_from_os_str = std::convert::TryFrom::try_from))]
124− pub url: Option<git::Url>,
125−
126− /// Output additional typically information provided by the server as part of the connection handshake.
127− #[clap(long)]
128− pub handshake_info: bool,
129−
130− /// Subcommands
131− #[clap(subcommand)]
132− pub cmd: Subcommands,
133− }
134−
135− #[derive(Debug, clap::Subcommand)]
136− #[clap(visible_alias = "remotes")]
137− pub enum Subcommands {
138− /// Print all references available on the remote.
139− #[cfg(any(feature = "gitoxide-core-async-client", feature = "gitoxide-core-blocking-client"))]
140− Refs,
141− /// Print all references available on the remote as filtered through ref-specs.
142− #[cfg(any(feature = "gitoxide-core-async-client", feature = "gitoxide-core-blocking-client"))]
143− RefMap {
144− /// Override the built-in and configured ref-specs with one or more of the given ones.
145− #[clap(parse(try_from_os_str = git::env::os_str_to_bstring))]
146− ref_spec: Vec<git_repository::bstr::BString>,
147− },
148− }
149−}
150−
151−pub mod mailmap {
152− #[derive(Debug, clap::Subcommand)]
153− pub enum Subcommands {
154− /// Print all entries in configured mailmaps, inform about errors as well.
155− Entries,
156− }
157−}
158−
159−pub mod odb {
160− #[derive(Debug, clap::Subcommand)]
161− pub enum Subcommands {
162− /// Print all object names.
163− Entries,
164− /// Provide general information about the object database.
165− Info,
166− }
167−}
168−
169−pub mod tree {
170− #[derive(Debug, clap::Subcommand)]
171− pub enum Subcommands {
172− /// Print entries in a given tree
173− Entries {
174− /// Traverse the entire tree and its subtrees respectively, not only this tree.
175− #[clap(long, short = 'r')]
176− recursive: bool,
177−
178− /// Provide files size as well. This is expensive as the object is decoded entirely.
179− #[clap(long, short = 'e')]
180− extended: bool,
181−
182− /// The tree to traverse, or the tree at `HEAD` if unspecified.
183− treeish: Option<String>,
184− },
185− /// Provide information about a tree.
186− Info {
187− /// Provide files size as well. This is expensive as the object is decoded entirely.
188− #[clap(long, short = 'e')]
189− extended: bool,
190− /// The tree to traverse, or the tree at `HEAD` if unspecified.
191− treeish: Option<String>,
192− },
193− }
194−}
195−
196−pub mod commit {
197− #[derive(Debug, clap::Subcommand)]
198− pub enum Subcommands {
199− /// Describe the current commit or the given one using the name of the closest annotated tag in its ancestry.
200− Describe {
201− /// Use annotated tag references only, not all tags.
202− #[clap(long, short = 't', conflicts_with("all-refs"))]
203− annotated_tags: bool,
204−
205− /// Use all references under the `ref/` namespaces, which includes tag references, local and remote branches.
206− #[clap(long, short = 'a', conflicts_with("annotated-tags"))]
207− all_refs: bool,
208−
209− /// Only follow the first parent when traversing the commit graph.
210− #[clap(long, short = 'f')]
211− first_parent: bool,
212−
213− /// Always display the long format, even if that would not be necessary as the id is located directly on a reference.
214− #[clap(long, short = 'l')]
215− long: bool,
216−
217− /// Consider only the given `n` candidates. This can take longer, but potentially produces more accurate results.
218− #[clap(long, short = 'c', default_value = "10")]
219− max_candidates: usize,
220−
221− /// Print information on stderr to inform about performance statistics
222− #[clap(long, short = 's')]
223− statistics: bool,
224−
225− #[clap(long)]
226− /// If there was no way to describe the commit, fallback to using the abbreviated input revision.
227− always: bool,
228−
229− /// A specification of the revision to use, or the current `HEAD` if unset.
230− rev_spec: Option<String>,
231− },
232− }
233−}
234−
235−pub mod credential {
236− #[derive(Debug, clap::Subcommand)]
237− pub enum Subcommands {
238− /// Get the credentials fed for `url=<url>` via STDIN.
239− #[clap(visible_alias = "get")]
240− Fill,
241− /// Approve the information piped via STDIN as obtained with last call to `fill`
242− #[clap(visible_alias = "store")]
243− Approve,
244− /// Try to resolve the given revspec and print the object names.
245− #[clap(visible_alias = "erase")]
246− Reject,
247− }
248−}
249−
250−pub mod revision {
251− #[derive(Debug, clap::Subcommand)]
252− #[clap(visible_alias = "rev", visible_alias = "r")]
253− pub enum Subcommands {
254− /// List all commits reachable from the given rev-spec.
255− #[clap(visible_alias = "l")]
256− List { spec: std::ffi::OsString },
257− /// Provide the revision specification like `@~1` to explain.
258− #[clap(visible_alias = "e")]
259− Explain { spec: std::ffi::OsString },
260− /// Try to resolve the given revspec and print the object names.
261− #[clap(visible_alias = "query", visible_alias = "parse", visible_alias = "p")]
262− Resolve {
263− /// Instead of resolving a rev-spec, explain what would be done for the first spec.
264− ///
265− /// Equivalent to the `explain` subcommand.
266− #[clap(short = 'e', long)]
267− explain: bool,
268− /// Show the first resulting object similar to how `git cat-file` would, but don't show the resolved spec.
269− #[clap(short = 'c', long, conflicts_with = "explain")]
270− cat_file: bool,
271− /// rev-specs like `@`, `@~1` or `HEAD^2`.
272− #[clap(required = true)]
273− specs: Vec<std::ffi::OsString>,
274− },
275− /// Return the names and hashes of all previously checked-out branches.
276− #[clap(visible_alias = "prev")]
277− PreviousBranches,
278− }
279−}
280−
281−///
282−pub mod free {
283− #[derive(Debug, clap::Subcommand)]
284− #[clap(visible_alias = "no-repo")]
285− pub enum Subcommands {
286− /// Subcommands for interacting with commit-graphs
287− #[clap(subcommand)]
288− CommitGraph(commitgraph::Subcommands),
289− /// Subcommands for interacting with mailmaps
290− Mailmap {
291− #[clap(flatten)]
292− cmd: mailmap::Platform,
293− },
294− /// Subcommands for interacting with pack files and indices
295− #[clap(subcommand)]
296− Pack(pack::Subcommands),
297− /// Subcommands for interacting with a worktree index, typically at .git/index
298− Index(index::Platform),
299− }
300−
301− ///
302− pub mod commitgraph {
303− use std::path::PathBuf;
304−
305− #[derive(Debug, clap::Subcommand)]
306− pub enum Subcommands {
307− /// Verify the integrity of a commit graph
308− Verify {
309− /// The path to '.git/objects/info/', '.git/objects/info/commit-graphs/', or '.git/objects/info/commit-graph' to validate.
310− path: PathBuf,
311− /// output statistical information about the pack
312− #[clap(long, short = 's')]
313− statistics: bool,
314− },
315− }
316− }
317−
318− pub mod index {
319− use std::path::PathBuf;
320−
321− #[derive(Debug, clap::Parser)]
322− pub struct Platform {
323− /// The object format to assume when reading files that don't inherently know about it, or when writing files.
324− #[clap(long, default_value_t = git_repository::hash::Kind::default(), possible_values(&["SHA1"]))]
325− pub object_hash: git_repository::hash::Kind,
326−
327− /// The path to the index file.
328− #[clap(short = 'i', long, default_value = ".git/index")]
329− pub index_path: PathBuf,
330−
331− /// Subcommands
332− #[clap(subcommand)]
333− pub cmd: Subcommands,
334− }
335−
336− #[derive(Debug, clap::Subcommand)]
337− pub enum Subcommands {
338− /// Validate constraints and assumptions of an index along with its integrity.
339− Verify,
340− /// Print all entries to standard output
341− Entries,
342− /// Print information about the index structure
343− Info {
344− /// Do not extract specific extension information to gain only a superficial idea of the index's composition.
345− #[clap(long)]
346− no_details: bool,
347− },
348− /// Checkout the index into a directory with exclusive write access, similar to what would happen during clone.
349− CheckoutExclusive {
350− /// The path to `.git` repository from which objects can be obtained to write the actual files referenced
351− /// in the index. Use this measure the impact on extracting objects on overall performance.
352− #[clap(long, short = 'r')]
353− repository: Option<PathBuf>,
354− /// Ignore errors and keep checking out as many files as possible, and report all errors at the end of the operation.
355− #[clap(long, short = 'k')]
356− keep_going: bool,
357− /// Enable to query the object database yet write only empty files. This is useful to measure the overhead of ODB query
358− /// compared to writing the bytes to disk.
359− #[clap(long, short = 'e', requires = "repository")]
360− empty_files: bool,
361− /// The directory into which to write all index entries.
362− directory: PathBuf,
363− },
364− }
365− }
366−
367− ///
368− pub mod pack {
369− use std::{ffi::OsString, path::PathBuf};
370−
371− use gitoxide_core as core;
372−
373− #[derive(Debug, clap::Subcommand)]
374− pub enum Subcommands {
375− /// Subcommands for interacting with pack indices (.idx)
376− #[clap(subcommand)]
377− Index(index::Subcommands),
378− /// Subcommands for interacting with multi-pack indices (named "multi-pack-index")
379− MultiIndex(multi_index::Platform),
380− /// Create a new pack with a set of objects.
381− Create {
382− #[clap(long, short = 'r')]
383− /// the directory containing the '.git' repository from which objects should be read.
384− repository: Option<PathBuf>,
385−
386− #[clap(long, short = 'e', possible_values(core::pack::create::ObjectExpansion::variants()))]
387− /// the way objects are expanded. They differ in costs.
388− ///
389− /// Possible values are "none" and "tree-traversal". Default is "none".
390− expansion: Option<core::pack::create::ObjectExpansion>,
391−
392− #[clap(long, default_value_t = 3, requires = "nondeterministic-count")]
393− /// The amount of threads to use when counting and the `--nondeterminisitc-count` flag is set, defaulting
394− /// to the globally configured threads.
395− ///
396− /// Use it to have different trade-offs between counting performance and cost in terms of CPU, as the scaling
397− /// here is everything but linear. The effectiveness of each core seems to be no more than 30%.
398− counting_threads: usize,
399−
400− #[clap(long)]
401− /// if set, the counting phase may be accelerated using multithreading.
402− ///
403− /// On the flip side, however, one will loose deterministic counting results which affects the
404− /// way the resulting pack is structured.
405− nondeterministic_count: bool,
406−
407− #[clap(long, short = 's')]
408− /// If set statistical information will be presented to inform about pack creation details.
409− /// It's a form of instrumentation for developers to help improve pack generation.
410− statistics: bool,
411−
412− #[clap(long)]
413− /// The size in megabytes for a cache to speed up pack access for packs with long delta chains.
414− /// It is shared among all threads, so 4 threads would use their own cache 1/4th of the size.
415− ///
416− /// If unset, no cache will be used.
417− pack_cache_size_mb: Option<usize>,
418−
419− #[clap(long)]
420− /// The size in megabytes for a cache to speed up accessing entire objects, bypassing object database access when hit.
421− /// It is shared among all threads, so 4 threads would use their own cache 1/4th of the size.
422− ///
423− /// This cache type is currently only effective when using the 'diff-tree' object expansion.
424− ///
425− /// If unset, no cache will be used.
426− object_cache_size_mb: Option<usize>,
427−
428− #[clap(long)]
429− /// if set, delta-objects whose base object wouldn't be in the pack will not be recompressed as base object, but instead
430− /// refer to its base object using its object id.
431− ///
432− /// This allows for smaller packs but requires the receiver of the pack to resolve these ids before storing the pack.
433− /// Packs produced with this option enabled are only valid in transit, but not at rest.
434− thin: bool,
435−
436− /// The directory into which to write the pack file.
437− #[clap(long, short = 'o')]
438− output_directory: Option<PathBuf>,
439−
440− /// The tips from which to start the commit graph iteration, either as fully qualified commit hashes
441− /// or as branch names.
442− ///
443− /// If empty, we expect to read objects on stdin and default to 'none' as expansion mode.
444− /// Otherwise the expansion mode is 'tree-traversal' by default.
445− tips: Vec<OsString>,
446− },
447− /// Use the git-protocol to receive a pack, emulating a clone.
448− #[cfg(any(feature = "gitoxide-core-async-client", feature = "gitoxide-core-blocking-client"))]
449− Receive {
450− /// The protocol version to use. Valid values are 1 and 2
451− #[clap(long, short = 'p')]
452− protocol: Option<core::net::Protocol>,
453−
454− /// the directory into which to write references. Existing files will be overwritten.
455− ///
456− /// Note that the directory will be created if needed.
457− #[clap(long, short = 'd')]
458− refs_directory: Option<PathBuf>,
459−
460− /// The URLs or path from which to receive the pack.
461− ///
462− /// See here for a list of supported URLs: <https://www.git-scm.com/docs/git-clone#_git_urls>
463− url: String,
464−
465− /// If set once or more times, these references will be fetched instead of all advertised ones.
466− ///
467− /// Note that this requires a reasonably modern git server.
468− #[clap(long = "reference", short = 'r')]
469− refs: Vec<String>,
470−
471− /// The directory into which to write the received pack and index.
472− ///
473− /// If unset, they will be discarded.
474− directory: Option<PathBuf>,
475− },
476− /// Dissolve a pack into its loose objects.
477− ///
478− /// Note that this effectively removes delta compression for an average compression of 2x, creating one file per object in the process.
479− /// Thus this should only be done to dissolve small packs after a fetch.
480− Explode {
481− #[clap(long)]
482− /// Read written objects back and assert they match their source. Fail the operation otherwise.
483− ///
484− /// Only relevant if an object directory is set.
485− verify: bool,
486−
487− /// delete the pack and index file after the operation is successful
488− #[clap(long)]
489− delete_pack: bool,
490−
491− /// The amount of checks to run
492− #[clap(
493− long,
494− short = 'c',
495− default_value = "all",
496− possible_values(core::pack::explode::SafetyCheck::variants())
497− )]
498− check: core::pack::explode::SafetyCheck,
499−
500− /// Compress bytes even when using the sink, i.e. no object directory is specified
501− ///
502− /// This helps to determine overhead related to compression. If unset, the sink will
503− /// only create hashes from bytes, which is usually limited by the speed at which input
504− /// can be obtained.
505− #[clap(long)]
506− sink_compress: bool,
507−
508− /// The '.pack' or '.idx' file to explode into loose objects
509− pack_path: PathBuf,
510−
511− /// The path into which all objects should be written. Commonly '.git/objects'
512− object_path: Option<PathBuf>,
513− },
514− /// Verify the integrity of a pack, index or multi-index file
515− Verify {
516− #[clap(flatten)]
517− args: VerifyOptions,
518−
519− /// The '.pack', '.idx' or 'multi-pack-index' file to validate.
520− path: PathBuf,
521− },
522− }
523−
524− #[derive(Debug, clap::Parser)]
525− pub struct VerifyOptions {
526− /// output statistical information
527− #[clap(long, short = 's')]
528− pub statistics: bool,
529− /// The algorithm used to verify packs. They differ in costs.
530− #[clap(
531− long,
532− short = 'a',
533− default_value = "less-time",
534− possible_values(core::pack::verify::Algorithm::variants())
535− )]
536− pub algorithm: core::pack::verify::Algorithm,
537−
538− #[clap(long, conflicts_with("re-encode"))]
539− /// Decode and parse tags, commits and trees to validate their correctness beyond hashing correctly.
540− ///
541− /// Malformed objects should not usually occur, but could be injected on purpose or accident.
542− /// This will reduce overall performance.
543− pub decode: bool,
544−
545− #[clap(long)]
546− /// Decode and parse tags, commits and trees to validate their correctness, and re-encode them.
547− ///
548− /// This flag is primarily to test the implementation of encoding, and requires to decode the object first.
549− /// Encoding an object after decoding it should yield exactly the same bytes.
550− /// This will reduce overall performance even more, as re-encoding requires to transform zero-copy objects into
551− /// owned objects, causing plenty of allocation to occur.
552− pub re_encode: bool,
553− }
554−
555− ///
556− pub mod multi_index {
557− use std::path::PathBuf;
558−
559− #[derive(Debug, clap::Parser)]
560− pub struct Platform {
561− /// The path to the index file.
562− #[clap(short = 'i', long, default_value = ".git/objects/pack/multi-pack-index")]
563− pub multi_index_path: PathBuf,
564−
565− /// Subcommands
566− #[clap(subcommand)]
567− pub cmd: Subcommands,
568− }
569−
570− #[derive(Debug, clap::Subcommand)]
571− pub enum Subcommands {
572− /// Display all entries of a multi-index: <oid> <pack-id> <pack-offset>
573− Entries,
574− /// Print general information about a multi-index file
575− Info,
576− /// Verify a multi-index quickly without inspecting objects themselves
577− Verify,
578− /// Create a multi-pack index from one or more pack index files, overwriting possibloy existing files.
579− Create {
580− /// Paths to the pack index files to read (with .idx extension).
581− ///
582− /// Note for the multi-index to be useful, it should be side-by-side with the supplied `.idx` files.
583− #[clap(required = true)]
584− index_paths: Vec<PathBuf>,
585− },
586− }
587− }
588−
589− ///
590− pub mod index {
591− use std::path::PathBuf;
592−
593− use gitoxide_core as core;
594−
595− #[derive(Debug, clap::Subcommand)]
596− pub enum Subcommands {
597− /// create a pack index from a pack data file.
598− Create {
599− /// Specify how to iterate the pack, defaults to 'verify'
600− ///
601− /// Valid values are
602− ///
603− /// **as-is** do not do anything and expect the pack file to be valid as per the trailing hash,
604− /// **verify** the input ourselves and validate that it matches with the hash provided in the pack,
605− /// **restore** hash the input ourselves and ignore failing entries, instead finish the pack with the hash we computed
606− /// to keep as many objects as possible.
607− #[clap(
608− long,
609− short = 'i',
610− default_value = "verify",
611− possible_values(core::pack::index::IterationMode::variants())
612− )]
613− iteration_mode: core::pack::index::IterationMode,
614−
615− /// Path to the pack file to read (with .pack extension).
616− ///
617− /// If unset, the pack file is expected on stdin.
618− #[clap(long, short = 'p')]
619− pack_path: Option<PathBuf>,
620−
621− /// The folder into which to place the pack and the generated index file
622− ///
623− /// If unset, only informational output will be provided to standard output.
624− directory: Option<PathBuf>,
625− },
626− }
627− }
628− }
629−
630− ///
631− pub mod mailmap {
632− use std::path::PathBuf;
633−
634− #[derive(Debug, clap::Parser)]
635− pub struct Platform {
636− /// The path to the mailmap file.
637− #[clap(short = 'p', long, default_value = ".mailmap")]
638− pub path: PathBuf,
639−
640− /// Subcommands
641− #[clap(subcommand)]
642− pub cmd: Subcommands,
643− }
644−
645− #[derive(Debug, clap::Subcommand)]
646− pub enum Subcommands {
647− /// Parse all entries in the mailmap and report malformed lines or collisions.
648− Verify,
649− }
650− }
651−}
652−
653−pub mod exclude {
654− use std::ffi::OsString;
655−
656− use git_repository as git;
657−
658− #[derive(Debug, clap::Subcommand)]
659− pub enum Subcommands {
660− /// Check if path-specs are excluded and print the result similar to `git check-ignore`.
661− Query {
662− /// Show actual ignore patterns instead of un-excluding an entry.
663− ///
664− /// That way one can understand why an entry might not be excluded.
665− #[clap(long, short = 'i')]
666− show_ignore_patterns: bool,
667− /// Additional patterns to use for exclusions. They have the highest priority.
668− ///
669− /// Useful for undoing previous patterns using the '!' prefix.
670− #[clap(long, short = 'p')]
671− patterns: Vec<OsString>,
672− /// The git path specifications to check for exclusion, or unset to read from stdin one per line.
673− #[clap(parse(try_from_os_str = std::convert::TryFrom::try_from))]
674− pathspecs: Vec<git::path::Spec>,
675− },
676− }
677−}
src/plumbing/options/free.rs+368−0
@@ -0,0 +1,368 @@
1+#[derive(Debug, clap::Subcommand)]
2+#[clap(visible_alias = "no-repo")]
3+pub enum Subcommands {
4+ /// Subcommands for interacting with commit-graphs
5+ #[clap(subcommand)]
6+ CommitGraph(commitgraph::Subcommands),
7+ /// Subcommands for interacting with mailmaps
8+ Mailmap {
9+ #[clap(flatten)]
10+ cmd: mailmap::Platform,
11+ },
12+ /// Subcommands for interacting with pack files and indices
13+ #[clap(subcommand)]
14+ Pack(pack::Subcommands),
15+ /// Subcommands for interacting with a worktree index, typically at .git/index
16+ Index(index::Platform),
17+}
18+
19+///
20+pub mod commitgraph {
21+ use std::path::PathBuf;
22+
23+ #[derive(Debug, clap::Subcommand)]
24+ pub enum Subcommands {
25+ /// Verify the integrity of a commit graph
26+ Verify {
27+ /// The path to '.git/objects/info/', '.git/objects/info/commit-graphs/', or '.git/objects/info/commit-graph' to validate.
28+ path: PathBuf,
29+ /// output statistical information about the pack
30+ #[clap(long, short = 's')]
31+ statistics: bool,
32+ },
33+ }
34+}
35+
36+pub mod index {
37+ use std::path::PathBuf;
38+
39+ #[derive(Debug, clap::Parser)]
40+ pub struct Platform {
41+ /// The object format to assume when reading files that don't inherently know about it, or when writing files.
42+ #[clap(long, default_value_t = git_repository::hash::Kind::default(), possible_values(&["SHA1"]))]
43+ pub object_hash: git_repository::hash::Kind,
44+
45+ /// The path to the index file.
46+ #[clap(short = 'i', long, default_value = ".git/index")]
47+ pub index_path: PathBuf,
48+
49+ /// Subcommands
50+ #[clap(subcommand)]
51+ pub cmd: Subcommands,
52+ }
53+
54+ #[derive(Debug, clap::Subcommand)]
55+ pub enum Subcommands {
56+ /// Validate constraints and assumptions of an index along with its integrity.
57+ Verify,
58+ /// Print all entries to standard output
59+ Entries,
60+ /// Print information about the index structure
61+ Info {
62+ /// Do not extract specific extension information to gain only a superficial idea of the index's composition.
63+ #[clap(long)]
64+ no_details: bool,
65+ },
66+ /// Checkout the index into a directory with exclusive write access, similar to what would happen during clone.
67+ CheckoutExclusive {
68+ /// The path to `.git` repository from which objects can be obtained to write the actual files referenced
69+ /// in the index. Use this measure the impact on extracting objects on overall performance.
70+ #[clap(long, short = 'r')]
71+ repository: Option<PathBuf>,
72+ /// Ignore errors and keep checking out as many files as possible, and report all errors at the end of the operation.
73+ #[clap(long, short = 'k')]
74+ keep_going: bool,
75+ /// Enable to query the object database yet write only empty files. This is useful to measure the overhead of ODB query
76+ /// compared to writing the bytes to disk.
77+ #[clap(long, short = 'e', requires = "repository")]
78+ empty_files: bool,
79+ /// The directory into which to write all index entries.
80+ directory: PathBuf,
81+ },
82+ }
83+}
84+
85+///
86+pub mod pack {
87+ use std::{ffi::OsString, path::PathBuf};
88+
89+ use gitoxide_core as core;
90+
91+ #[derive(Debug, clap::Subcommand)]
92+ pub enum Subcommands {
93+ /// Subcommands for interacting with pack indices (.idx)
94+ #[clap(subcommand)]
95+ Index(index::Subcommands),
96+ /// Subcommands for interacting with multi-pack indices (named "multi-pack-index")
97+ MultiIndex(multi_index::Platform),
98+ /// Create a new pack with a set of objects.
99+ Create {
100+ #[clap(long, short = 'r')]
101+ /// the directory containing the '.git' repository from which objects should be read.
102+ repository: Option<PathBuf>,
103+
104+ #[clap(long, short = 'e', possible_values(core::pack::create::ObjectExpansion::variants()))]
105+ /// the way objects are expanded. They differ in costs.
106+ ///
107+ /// Possible values are "none" and "tree-traversal". Default is "none".
108+ expansion: Option<core::pack::create::ObjectExpansion>,
109+
110+ #[clap(long, default_value_t = 3, requires = "nondeterministic-count")]
111+ /// The amount of threads to use when counting and the `--nondeterminisitc-count` flag is set, defaulting
112+ /// to the globally configured threads.
113+ ///
114+ /// Use it to have different trade-offs between counting performance and cost in terms of CPU, as the scaling
115+ /// here is everything but linear. The effectiveness of each core seems to be no more than 30%.
116+ counting_threads: usize,
117+
118+ #[clap(long)]
119+ /// if set, the counting phase may be accelerated using multithreading.
120+ ///
121+ /// On the flip side, however, one will loose deterministic counting results which affects the
122+ /// way the resulting pack is structured.
123+ nondeterministic_count: bool,
124+
125+ #[clap(long, short = 's')]
126+ /// If set statistical information will be presented to inform about pack creation details.
127+ /// It's a form of instrumentation for developers to help improve pack generation.
128+ statistics: bool,
129+
130+ #[clap(long)]
131+ /// The size in megabytes for a cache to speed up pack access for packs with long delta chains.
132+ /// It is shared among all threads, so 4 threads would use their own cache 1/4th of the size.
133+ ///
134+ /// If unset, no cache will be used.
135+ pack_cache_size_mb: Option<usize>,
136+
137+ #[clap(long)]
138+ /// The size in megabytes for a cache to speed up accessing entire objects, bypassing object database access when hit.
139+ /// It is shared among all threads, so 4 threads would use their own cache 1/4th of the size.
140+ ///
141+ /// This cache type is currently only effective when using the 'diff-tree' object expansion.
142+ ///
143+ /// If unset, no cache will be used.
144+ object_cache_size_mb: Option<usize>,
145+
146+ #[clap(long)]
147+ /// if set, delta-objects whose base object wouldn't be in the pack will not be recompressed as base object, but instead
148+ /// refer to its base object using its object id.
149+ ///
150+ /// This allows for smaller packs but requires the receiver of the pack to resolve these ids before storing the pack.
151+ /// Packs produced with this option enabled are only valid in transit, but not at rest.
152+ thin: bool,
153+
154+ /// The directory into which to write the pack file.
155+ #[clap(long, short = 'o')]
156+ output_directory: Option<PathBuf>,
157+
158+ /// The tips from which to start the commit graph iteration, either as fully qualified commit hashes
159+ /// or as branch names.
160+ ///
161+ /// If empty, we expect to read objects on stdin and default to 'none' as expansion mode.
162+ /// Otherwise the expansion mode is 'tree-traversal' by default.
163+ tips: Vec<OsString>,
164+ },
165+ /// Use the git-protocol to receive a pack, emulating a clone.
166+ #[cfg(any(feature = "gitoxide-core-async-client", feature = "gitoxide-core-blocking-client"))]
167+ Receive {
168+ /// The protocol version to use. Valid values are 1 and 2
169+ #[clap(long, short = 'p')]
170+ protocol: Option<core::net::Protocol>,
171+
172+ /// the directory into which to write references. Existing files will be overwritten.
173+ ///
174+ /// Note that the directory will be created if needed.
175+ #[clap(long, short = 'd')]
176+ refs_directory: Option<PathBuf>,
177+
178+ /// The URLs or path from which to receive the pack.
179+ ///
180+ /// See here for a list of supported URLs: <https://www.git-scm.com/docs/git-clone#_git_urls>
181+ url: String,
182+
183+ /// If set once or more times, these references will be fetched instead of all advertised ones.
184+ ///
185+ /// Note that this requires a reasonably modern git server.
186+ #[clap(long = "reference", short = 'r')]
187+ refs: Vec<String>,
188+
189+ /// The directory into which to write the received pack and index.
190+ ///
191+ /// If unset, they will be discarded.
192+ directory: Option<PathBuf>,
193+ },
194+ /// Dissolve a pack into its loose objects.
195+ ///
196+ /// Note that this effectively removes delta compression for an average compression of 2x, creating one file per object in the process.
197+ /// Thus this should only be done to dissolve small packs after a fetch.
198+ Explode {
199+ #[clap(long)]
200+ /// Read written objects back and assert they match their source. Fail the operation otherwise.
201+ ///
202+ /// Only relevant if an object directory is set.
203+ verify: bool,
204+
205+ /// delete the pack and index file after the operation is successful
206+ #[clap(long)]
207+ delete_pack: bool,
208+
209+ /// The amount of checks to run
210+ #[clap(
211+ long,
212+ short = 'c',
213+ default_value = "all",
214+ possible_values(core::pack::explode::SafetyCheck::variants())
215+ )]
216+ check: core::pack::explode::SafetyCheck,
217+
218+ /// Compress bytes even when using the sink, i.e. no object directory is specified
219+ ///
220+ /// This helps to determine overhead related to compression. If unset, the sink will
221+ /// only create hashes from bytes, which is usually limited by the speed at which input
222+ /// can be obtained.
223+ #[clap(long)]
224+ sink_compress: bool,
225+
226+ /// The '.pack' or '.idx' file to explode into loose objects
227+ pack_path: PathBuf,
228+
229+ /// The path into which all objects should be written. Commonly '.git/objects'
230+ object_path: Option<PathBuf>,
231+ },
232+ /// Verify the integrity of a pack, index or multi-index file
233+ Verify {
234+ #[clap(flatten)]
235+ args: VerifyOptions,
236+
237+ /// The '.pack', '.idx' or 'multi-pack-index' file to validate.
238+ path: PathBuf,
239+ },
240+ }
241+
242+ #[derive(Debug, clap::Parser)]
243+ pub struct VerifyOptions {
244+ /// output statistical information
245+ #[clap(long, short = 's')]
246+ pub statistics: bool,
247+ /// The algorithm used to verify packs. They differ in costs.
248+ #[clap(
249+ long,
250+ short = 'a',
251+ default_value = "less-time",
252+ possible_values(core::pack::verify::Algorithm::variants())
253+ )]
254+ pub algorithm: core::pack::verify::Algorithm,
255+
256+ #[clap(long, conflicts_with("re-encode"))]
257+ /// Decode and parse tags, commits and trees to validate their correctness beyond hashing correctly.
258+ ///
259+ /// Malformed objects should not usually occur, but could be injected on purpose or accident.
260+ /// This will reduce overall performance.
261+ pub decode: bool,
262+
263+ #[clap(long)]
264+ /// Decode and parse tags, commits and trees to validate their correctness, and re-encode them.
265+ ///
266+ /// This flag is primarily to test the implementation of encoding, and requires to decode the object first.
267+ /// Encoding an object after decoding it should yield exactly the same bytes.
268+ /// This will reduce overall performance even more, as re-encoding requires to transform zero-copy objects into
269+ /// owned objects, causing plenty of allocation to occur.
270+ pub re_encode: bool,
271+ }
272+
273+ ///
274+ pub mod multi_index {
275+ use std::path::PathBuf;
276+
277+ #[derive(Debug, clap::Parser)]
278+ pub struct Platform {
279+ /// The path to the index file.
280+ #[clap(short = 'i', long, default_value = ".git/objects/pack/multi-pack-index")]
281+ pub multi_index_path: PathBuf,
282+
283+ /// Subcommands
284+ #[clap(subcommand)]
285+ pub cmd: Subcommands,
286+ }
287+
288+ #[derive(Debug, clap::Subcommand)]
289+ pub enum Subcommands {
290+ /// Display all entries of a multi-index: <oid> <pack-id> <pack-offset>
291+ Entries,
292+ /// Print general information about a multi-index file
293+ Info,
294+ /// Verify a multi-index quickly without inspecting objects themselves
295+ Verify,
296+ /// Create a multi-pack index from one or more pack index files, overwriting possibloy existing files.
297+ Create {
298+ /// Paths to the pack index files to read (with .idx extension).
299+ ///
300+ /// Note for the multi-index to be useful, it should be side-by-side with the supplied `.idx` files.
301+ #[clap(required = true)]
302+ index_paths: Vec<PathBuf>,
303+ },
304+ }
305+ }
306+
307+ ///
308+ pub mod index {
309+ use std::path::PathBuf;
310+
311+ use gitoxide_core as core;
312+
313+ #[derive(Debug, clap::Subcommand)]
314+ pub enum Subcommands {
315+ /// create a pack index from a pack data file.
316+ Create {
317+ /// Specify how to iterate the pack, defaults to 'verify'
318+ ///
319+ /// Valid values are
320+ ///
321+ /// **as-is** do not do anything and expect the pack file to be valid as per the trailing hash,
322+ /// **verify** the input ourselves and validate that it matches with the hash provided in the pack,
323+ /// **restore** hash the input ourselves and ignore failing entries, instead finish the pack with the hash we computed
324+ /// to keep as many objects as possible.
325+ #[clap(
326+ long,
327+ short = 'i',
328+ default_value = "verify",
329+ possible_values(core::pack::index::IterationMode::variants())
330+ )]
331+ iteration_mode: core::pack::index::IterationMode,
332+
333+ /// Path to the pack file to read (with .pack extension).
334+ ///
335+ /// If unset, the pack file is expected on stdin.
336+ #[clap(long, short = 'p')]
337+ pack_path: Option<PathBuf>,
338+
339+ /// The folder into which to place the pack and the generated index file
340+ ///
341+ /// If unset, only informational output will be provided to standard output.
342+ directory: Option<PathBuf>,
343+ },
344+ }
345+ }
346+}
347+
348+///
349+pub mod mailmap {
350+ use std::path::PathBuf;
351+
352+ #[derive(Debug, clap::Parser)]
353+ pub struct Platform {
354+ /// The path to the mailmap file.
355+ #[clap(short = 'p', long, default_value = ".mailmap")]
356+ pub path: PathBuf,
357+
358+ /// Subcommands
359+ #[clap(subcommand)]
360+ pub cmd: Subcommands,
361+ }
362+
363+ #[derive(Debug, clap::Subcommand)]
364+ pub enum Subcommands {
365+ /// Parse all entries in the mailmap and report malformed lines or collisions.
366+ Verify,
367+ }
368+}
src/plumbing/options/mod.rs+319−0
@@ -0,0 +1,319 @@
1+use std::path::PathBuf;
2+
3+use git_repository as git;
4+use git_repository::bstr::BString;
5+use gitoxide_core as core;
6+
7+#[derive(Debug, clap::Parser)]
8+#[clap(name = "gix-plumbing", about = "The git underworld", version = clap::crate_version!())]
9+#[clap(subcommand_required = true)]
10+#[clap(arg_required_else_help = true)]
11+pub struct Args {
12+ /// The repository to access.
13+ #[clap(short = 'r', long, default_value = ".")]
14+ pub repository: PathBuf,
15+
16+ /// Add these values to the configuration in the form of `key=value` or `key`.
17+ ///
18+ /// For example, if `key` is `core.abbrev`, set configuration like `[core] abbrev = key`,
19+ /// or `remote.origin.url = foo` to set `[remote "origin"] url = foo`.
20+ #[clap(long, short = 'c', parse(try_from_os_str = git::env::os_str_to_bstring))]
21+ pub config: Vec<BString>,
22+
23+ #[clap(long, short = 't')]
24+ /// The amount of threads to use for some operations.
25+ ///
26+ /// If unset, or the value is 0, there is no limit and all logical cores can be used.
27+ pub threads: Option<usize>,
28+
29+ /// Display verbose messages and progress information
30+ #[clap(long, short = 'v')]
31+ pub verbose: bool,
32+
33+ /// Bring up a terminal user interface displaying progress visually
34+ #[cfg(feature = "prodash-render-tui")]
35+ #[clap(long, conflicts_with("verbose"))]
36+ pub progress: bool,
37+
38+ /// The progress TUI will stay up even though the work is already completed.
39+ ///
40+ /// Use this to be able to read progress messages or additional information visible in the TUI log pane.
41+ #[cfg(feature = "prodash-render-tui")]
42+ #[clap(long, conflicts_with("verbose"), requires("progress"))]
43+ pub progress_keep_open: bool,
44+
45+ /// Determine the format to use when outputting statistics.
46+ #[clap(
47+ long,
48+ short = 'f',
49+ default_value = "human",
50+ possible_values(core::OutputFormat::variants())
51+ )]
52+ pub format: core::OutputFormat,
53+
54+ /// The object format to assume when reading files that don't inherently know about it, or when writing files.
55+ #[clap(long, default_value_t = git_repository::hash::Kind::default(), possible_values(&["SHA1"]))]
56+ pub object_hash: git_repository::hash::Kind,
57+
58+ #[clap(subcommand)]
59+ pub cmd: Subcommands,
60+}
61+
62+#[derive(Debug, clap::Subcommand)]
63+pub enum Subcommands {
64+ /// Interact with the object database.
65+ #[clap(subcommand)]
66+ Odb(odb::Subcommands),
67+ /// Interact with tree objects.
68+ #[clap(subcommand)]
69+ Tree(tree::Subcommands),
70+ /// Interact with commit objects.
71+ #[clap(subcommand)]
72+ Commit(commit::Subcommands),
73+ /// Verify the integrity of the entire repository
74+ Verify {
75+ #[clap(flatten)]
76+ args: free::pack::VerifyOptions,
77+ },
78+ /// Query and obtain information about revisions.
79+ #[clap(subcommand)]
80+ Revision(revision::Subcommands),
81+ /// A program just like `git credential`.
82+ #[clap(subcommand)]
83+ Credential(credential::Subcommands),
84+ /// Interact with the mailmap.
85+ #[clap(subcommand)]
86+ Mailmap(mailmap::Subcommands),
87+ /// Interact with the remote hosts.
88+ Remote(remote::Platform),
89+ /// Interact with the exclude files like .gitignore.
90+ #[clap(subcommand)]
91+ Exclude(exclude::Subcommands),
92+ #[clap(subcommand)]
93+ Progress(progress::Subcommands),
94+ Config(config::Platform),
95+ /// Subcommands that need no git repository to run.
96+ #[clap(subcommand)]
97+ Free(free::Subcommands),
98+}
99+
100+pub mod progress {
101+
102+ #[derive(Debug, clap::Subcommand)]
103+ pub enum Subcommands {
104+ /// Show the implementation progress of gitoxide based on the git configuration that it consumes.
105+ Show,
106+ }
107+}
108+
109+pub mod config {
110+ /// Print all entries in a configuration file or access other sub-commands
111+ #[derive(Debug, clap::Parser)]
112+ #[clap(subcommand_required(false))]
113+ pub struct Platform {
114+ /// The filter terms to limit the output to matching sections and subsections only.
115+ ///
116+ /// Typical filters are `branch` or `remote.origin` or `remote.or*` - git-style globs are supported
117+ /// and comparisons are case-insensitive.
118+ pub filter: Vec<String>,
119+ }
120+}
121+
122+pub mod remote {
123+ use git_repository as git;
124+
125+ #[derive(Debug, clap::Parser)]
126+ pub struct Platform {
127+ /// The name of the remote to connect to.
128+ ///
129+ /// If unset, the current branch will determine the remote.
130+ #[clap(long, short = 'n')]
131+ pub name: Option<String>,
132+
133+ /// Connect directly to the given URL, forgoing any configuration from the repository.
134+ #[clap(long, short = 'u', conflicts_with("name"), parse(try_from_os_str = std::convert::TryFrom::try_from))]
135+ pub url: Option<git::Url>,
136+
137+ /// Output additional typically information provided by the server as part of the connection handshake.
138+ #[clap(long)]
139+ pub handshake_info: bool,
140+
141+ /// Subcommands
142+ #[clap(subcommand)]
143+ pub cmd: Subcommands,
144+ }
145+
146+ #[derive(Debug, clap::Subcommand)]
147+ #[clap(visible_alias = "remotes")]
148+ pub enum Subcommands {
149+ /// Print all references available on the remote.
150+ #[cfg(any(feature = "gitoxide-core-async-client", feature = "gitoxide-core-blocking-client"))]
151+ Refs,
152+ /// Print all references available on the remote as filtered through ref-specs.
153+ #[cfg(any(feature = "gitoxide-core-async-client", feature = "gitoxide-core-blocking-client"))]
154+ RefMap {
155+ /// Override the built-in and configured ref-specs with one or more of the given ones.
156+ #[clap(parse(try_from_os_str = git::env::os_str_to_bstring))]
157+ ref_spec: Vec<git_repository::bstr::BString>,
158+ },
159+ }
160+}
161+
162+pub mod mailmap {
163+ #[derive(Debug, clap::Subcommand)]
164+ pub enum Subcommands {
165+ /// Print all entries in configured mailmaps, inform about errors as well.
166+ Entries,
167+ }
168+}
169+
170+pub mod odb {
171+ #[derive(Debug, clap::Subcommand)]
172+ pub enum Subcommands {
173+ /// Print all object names.
174+ Entries,
175+ /// Provide general information about the object database.
176+ Info,
177+ }
178+}
179+
180+pub mod tree {
181+ #[derive(Debug, clap::Subcommand)]
182+ pub enum Subcommands {
183+ /// Print entries in a given tree
184+ Entries {
185+ /// Traverse the entire tree and its subtrees respectively, not only this tree.
186+ #[clap(long, short = 'r')]
187+ recursive: bool,
188+
189+ /// Provide files size as well. This is expensive as the object is decoded entirely.
190+ #[clap(long, short = 'e')]
191+ extended: bool,
192+
193+ /// The tree to traverse, or the tree at `HEAD` if unspecified.
194+ treeish: Option<String>,
195+ },
196+ /// Provide information about a tree.
197+ Info {
198+ /// Provide files size as well. This is expensive as the object is decoded entirely.
199+ #[clap(long, short = 'e')]
200+ extended: bool,
201+ /// The tree to traverse, or the tree at `HEAD` if unspecified.
202+ treeish: Option<String>,
203+ },
204+ }
205+}
206+
207+pub mod commit {
208+ #[derive(Debug, clap::Subcommand)]
209+ pub enum Subcommands {
210+ /// Describe the current commit or the given one using the name of the closest annotated tag in its ancestry.
211+ Describe {
212+ /// Use annotated tag references only, not all tags.
213+ #[clap(long, short = 't', conflicts_with("all-refs"))]
214+ annotated_tags: bool,
215+
216+ /// Use all references under the `ref/` namespaces, which includes tag references, local and remote branches.
217+ #[clap(long, short = 'a', conflicts_with("annotated-tags"))]
218+ all_refs: bool,
219+
220+ /// Only follow the first parent when traversing the commit graph.
221+ #[clap(long, short = 'f')]
222+ first_parent: bool,
223+
224+ /// Always display the long format, even if that would not be necessary as the id is located directly on a reference.
225+ #[clap(long, short = 'l')]
226+ long: bool,
227+
228+ /// Consider only the given `n` candidates. This can take longer, but potentially produces more accurate results.
229+ #[clap(long, short = 'c', default_value = "10")]
230+ max_candidates: usize,
231+
232+ /// Print information on stderr to inform about performance statistics
233+ #[clap(long, short = 's')]
234+ statistics: bool,
235+
236+ #[clap(long)]
237+ /// If there was no way to describe the commit, fallback to using the abbreviated input revision.
238+ always: bool,
239+
240+ /// A specification of the revision to use, or the current `HEAD` if unset.
241+ rev_spec: Option<String>,
242+ },
243+ }
244+}
245+
246+pub mod credential {
247+ #[derive(Debug, clap::Subcommand)]
248+ pub enum Subcommands {
249+ /// Get the credentials fed for `url=<url>` via STDIN.
250+ #[clap(visible_alias = "get")]
251+ Fill,
252+ /// Approve the information piped via STDIN as obtained with last call to `fill`
253+ #[clap(visible_alias = "store")]
254+ Approve,
255+ /// Try to resolve the given revspec and print the object names.
256+ #[clap(visible_alias = "erase")]
257+ Reject,
258+ }
259+}
260+
261+pub mod revision {
262+ #[derive(Debug, clap::Subcommand)]
263+ #[clap(visible_alias = "rev", visible_alias = "r")]
264+ pub enum Subcommands {
265+ /// List all commits reachable from the given rev-spec.
266+ #[clap(visible_alias = "l")]
267+ List { spec: std::ffi::OsString },
268+ /// Provide the revision specification like `@~1` to explain.
269+ #[clap(visible_alias = "e")]
270+ Explain { spec: std::ffi::OsString },
271+ /// Try to resolve the given revspec and print the object names.
272+ #[clap(visible_alias = "query", visible_alias = "parse", visible_alias = "p")]
273+ Resolve {
274+ /// Instead of resolving a rev-spec, explain what would be done for the first spec.
275+ ///
276+ /// Equivalent to the `explain` subcommand.
277+ #[clap(short = 'e', long)]
278+ explain: bool,
279+ /// Show the first resulting object similar to how `git cat-file` would, but don't show the resolved spec.
280+ #[clap(short = 'c', long, conflicts_with = "explain")]
281+ cat_file: bool,
282+ /// rev-specs like `@`, `@~1` or `HEAD^2`.
283+ #[clap(required = true)]
284+ specs: Vec<std::ffi::OsString>,
285+ },
286+ /// Return the names and hashes of all previously checked-out branches.
287+ #[clap(visible_alias = "prev")]
288+ PreviousBranches,
289+ }
290+}
291+
292+pub mod exclude {
293+ use std::ffi::OsString;
294+
295+ use git_repository as git;
296+
297+ #[derive(Debug, clap::Subcommand)]
298+ pub enum Subcommands {
299+ /// Check if path-specs are excluded and print the result similar to `git check-ignore`.
300+ Query {
301+ /// Show actual ignore patterns instead of un-excluding an entry.
302+ ///
303+ /// That way one can understand why an entry might not be excluded.
304+ #[clap(long, short = 'i')]
305+ show_ignore_patterns: bool,
306+ /// Additional patterns to use for exclusions. They have the highest priority.
307+ ///
308+ /// Useful for undoing previous patterns using the '!' prefix.
309+ #[clap(long, short = 'p')]
310+ patterns: Vec<OsString>,
311+ /// The git path specifications to check for exclusion, or unset to read from stdin one per line.
312+ #[clap(parse(try_from_os_str = std::convert::TryFrom::try_from))]
313+ pathspecs: Vec<git::path::Spec>,
314+ },
315+ }
316+}
317+
318+///
319+pub mod free;
src/plumbing/progress.rs+44−0
@@ -0,0 +1,44 @@
1+use crosstermion::crossterm::style::Stylize;
2+use std::fmt::{Display, Formatter};
3+
4+enum Usage {
5+ InModule(&'static str),
6+}
7+use Usage::*;
8+
9+impl Display for Usage {
10+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
11+ match self {
12+ InModule(m) => write!(f, "mod {m}"),
13+ }
14+ }
15+}
16+
17+struct Record {
18+ config: &'static str,
19+ usage: Usage,
20+ deviation: Option<&'static str>,
21+}
22+
23+static GIT_CONFIG: &[Record] = &[Record {
24+ config: "pack.threads",
25+ usage: InModule("remote::connection::fetch"),
26+ deviation: Some("if unset, it uses all threads as opposed to just 1"),
27+}];
28+
29+/// A programmatic way to record and display progress.
30+pub fn show_progress() -> anyhow::Result<()> {
31+ for Record {
32+ config,
33+ usage,
34+ deviation,
35+ } in GIT_CONFIG
36+ {
37+ println!(
38+ "{}: {usage}{}",
39+ config.bold(),
40+ deviation.map(|d| format!(" ({d})")).unwrap_or_default().dark_grey()
41+ );
42+ }
43+ Ok(())
44+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t