Unified · Split
| @@ -1835,6 +1835,7 @@ dependencies = [ · 1834 unmodified lines | ||
| 1835 | 1835 | "git-repository", |
| 1836 | 1836 | "git-transport", |
| 1837 | 1837 | "gitoxide-core", |
| 1838 | + "owo-colors", | |
| 1838 | 1839 | "prodash", |
| 1839 | 1840 | ] |
| 1840 | 1841 | |
| @@ -2380,6 +2381,12 @@ dependencies = [ · 539 unmodified lines | ||
| 2380 | 2381 | "winapi", |
| 2381 | 2382 | ] |
| 2382 | 2383 | |
| 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 | + | |
| 2383 | 2390 | [[package]] |
| 2384 | 2391 | name = "parking" |
| 2385 | 2392 | version = "2.0.0" |
| @@ -92,6 +92,9 @@ env_logger = { version = "0.9.0", default-features = false } · 91 unmodified lines | ||
| 92 | 92 | crosstermion = { version = "0.10.1", optional = true, default-features = false } |
| 93 | 93 | futures-lite = { version = "1.12.0", optional = true, default-features = false, features = ["std"] } |
| 94 | 94 | |
| 95 | +# for show-progress | |
| 96 | +owo-colors = "3.5.0" | |
| 97 | + | |
| 95 | 98 | document-features = { version = "0.2.0", optional = true } |
| 96 | 99 | |
| 97 | 100 | [profile.dev.package] |
| @@ -27,6 +27,10 @@ Please see _'Development Status'_ for a listing of all crates and their capabili · 26 unmodified lines | ||
| 27 | 27 | * Based on the [git-hours] algorithm. |
| 28 | 28 | * See the [discussion][git-hours-discussion] for some performance data. |
| 29 | 29 | * **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 | 34 | * **config** - list the complete git configuration in human-readable form and optionally filter sections by name. |
| 31 | 35 | * **exclude** |
| 32 | 36 | * [x] **query** - check if path specs are excluded via gits exclusion rules like `.gitignore`. |
| @@ -14,8 +14,12 @@ use gitoxide_core as core; · 13 unmodified lines | ||
| 14 | 14 | use gitoxide_core::pack::verify; |
| 15 | 15 | |
| 16 | 16 | 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, | |
| 19 | 23 | }, |
| 20 | 24 | shared::pretty::prepare_and_run, |
| 21 | 25 | }; |
| @@ -111,6 +115,7 @@ pub fn main() -> Result<()> { · 89 unmodified lines | ||
| 111 | 115 | })?; |
| 112 | 116 | |
| 113 | 117 | match cmd { |
| 118 | + Subcommands::Progress(progress::Subcommands::Show) => show_progress(), | |
| 114 | 119 | Subcommands::Credential(cmd) => core::repository::credential( |
| 115 | 120 | repository(Mode::StrictWithGitInstallConfig)?, |
| 116 | 121 | match cmd { |
| @@ -1,4 +1,8 @@ | ||
| 1 | 1 | mod main; |
| 2 | 2 | pub use main::main; |
| 3 | 3 | |
| 4 | +#[path = "progress.rs"] | |
| 5 | +mod progress_impl; | |
| 6 | +pub use progress_impl::show_progress; | |
| 7 | + | |
| 4 | 8 | mod options; |
| @@ -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 | −} | |
| @@ -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 | +} | |
| @@ -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; | |
| @@ -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 | +} | |