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
1835 "git-repository",1835 "git-repository",
1836 "git-transport",1836 "git-transport",
1837 "gitoxide-core",1837 "gitoxide-core",
1838 "owo-colors",
1838 "prodash",1839 "prodash",
1839]1840]
1840 1841
@@ -2380,6 +2381,12 @@ dependencies = [ · 539 unmodified lines
2380 "winapi",2381 "winapi",
2381]2382]
2382 2383
2384[[package]]
2385name = "owo-colors"
2386version = "3.5.0"
2387source = "registry+https://github.com/rust-lang/crates.io-index"
2388checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
2389
2383[[package]]2390[[package]]
2384name = "parking"2391name = "parking"
2385version = "2.0.0"2392version = "2.0.0"
Cargo.toml+3−0
@@ -92,6 +92,9 @@ env_logger = { version = "0.9.0", default-features = false } · 91 unmodified lines
92crosstermion = { version = "0.10.1", optional = true, default-features = false }92crosstermion = { version = "0.10.1", optional = true, default-features = false }
93futures-lite = { version = "1.12.0", optional = true, default-features = false, features = ["std"] }93futures-lite = { version = "1.12.0", optional = true, default-features = false, features = ["std"] }
94 94
95# for show-progress
96owo-colors = "3.5.0"
97
95document-features = { version = "0.2.0", optional = true }98document-features = { version = "0.2.0", optional = true }
96 99
97[profile.dev.package]100[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
27 * Based on the [git-hours] algorithm.27 * Based on the [git-hours] algorithm.
28 * See the [discussion][git-hours-discussion] for some performance data.28 * See the [discussion][git-hours-discussion] for some performance data.
29 * **the `gix` program** _(plumbing)_ - lower level commands for use in automation29 * **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.
30 * **config** - list the complete git configuration in human-readable form and optionally filter sections by name.34 * **config** - list the complete git configuration in human-readable form and optionally filter sections by name.
31 * **exclude**35 * **exclude**
32 * [x] **query** - check if path specs are excluded via gits exclusion rules like `.gitignore`.36 * [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
14use gitoxide_core::pack::verify;14use gitoxide_core::pack::verify;
15 15
16use crate::{16use crate::{
17 plumbing::options::{17 plumbing::{
18 commit, config, credential, exclude, free, mailmap, odb, remote, revision, tree, Args, Subcommands,18 options::{
19 commit, config, credential, exclude, free, mailmap, odb, progress, remote, revision, tree, Args,
20 Subcommands,
21 },
22 show_progress,
19 },23 },
20 shared::pretty::prepare_and_run,24 shared::pretty::prepare_and_run,
21};25};
@@ -111,6 +115,7 @@ pub fn main() -> Result<()> { · 89 unmodified lines
111 })?;115 })?;
112 116
113 match cmd {117 match cmd {
118 Subcommands::Progress(progress::Subcommands::Show) => show_progress(),
114 Subcommands::Credential(cmd) => core::repository::credential(119 Subcommands::Credential(cmd) => core::repository::credential(
115 repository(Mode::StrictWithGitInstallConfig)?,120 repository(Mode::StrictWithGitInstallConfig)?,
116 match cmd {121 match cmd {
src/plumbing/mod.rs+4−0
@@ -1,4 +1,8 @@
1mod main;1mod main;
2pub use main::main;2pub use main::main;
3 3
4#[path = "progress.rs"]
5mod progress_impl;
6pub use progress_impl::show_progress;
7
4mod options;8mod options;
src/plumbing/options.rs+0−677
@@ -1,677 +0,0 @@
1use std::path::PathBuf;
2
3use git_repository as git;
4use git_repository::bstr::BString;
5use 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)]
11pub 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)]
63pub 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
98pub 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
111pub 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
151pub 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
159pub 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
169pub 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
196pub 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
235pub 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
250pub 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///
282pub 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
653pub 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")]
3pub 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///
20pub 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
36pub 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///
86pub 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///
349pub 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 @@
1use std::path::PathBuf;
2
3use git_repository as git;
4use git_repository::bstr::BString;
5use 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)]
11pub 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)]
63pub 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
100pub 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
109pub 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
122pub 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
162pub 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
170pub 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
180pub 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
207pub 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
246pub 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
261pub 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
292pub 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///
319pub mod free;
src/plumbing/progress.rs+44−0
@@ -0,0 +1,44 @@
1use crosstermion::crossterm::style::Stylize;
2use std::fmt::{Display, Formatter};
3
4enum Usage {
5 InModule(&'static str),
6}
7use Usage::*;
8
9impl 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
17struct Record {
18 config: &'static str,
19 usage: Usage,
20 deviation: Option<&'static str>,
21}
22
23static 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.
30pub 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