Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

CLI Parser Notes

rsmultigit uses clap 4 (derive macros) for command-line parsing. This page documents parser limitations we’ve hit and the workarounds we’ve chosen, so that future contributors don’t re-investigate the same dead ends.

Command categories in --help

What we wanted. Group the ~30 subcommands under headings (Inspection, Sync, Mutating, Build, Maintenance, Correctness, Meta) so rsmultigit --help is scannable instead of a flat alphabetical wall.

What clap actually supports. In clap 4, #[command(help_heading = "...")] (and the builder equivalent Command::help_heading) only group arguments, not subcommands. Per-subcommand-variant help_heading doesn’t compile:

error[E0599]: no method named `help_heading` found for struct `clap::Command`

Upstream tracks this as an unresolved feature request (clap-rs/clap#4416, open as of clap 4.6).

What we do. Keep the flat alphabetical list in --help. Document the intended categories in the README / these docs for human readers. The enum arms themselves stay ungrouped because adding source-level categories without corresponding help-output categories would just be noise.

What we considered and rejected. Intercepting --help to emit a custom grouped listing (~50 lines): doable but adds a maintenance surface — every new subcommand has to be added to the grouping table as well as to the enum, and the table can silently drift out of sync. Not worth it for a cosmetic win unless the flat help becomes actively painful.

Aliases and shell completion

What we wanted. alias mg=rsmultigit should preserve tab completion.

What actually happens. Shell completions are bound to a specific program name — the name is baked into the generated completion script. Generating with rsmultigit complete bash produces a _rsmultigit function registered against the literal word rsmultigit. Typing mg <TAB> doesn’t trigger it.

Workaround. Reuse the existing completion function by telling the shell:

alias mg=rsmultigit
complete -F _rsmultigit mg   # bash
compdef mg=rsmultigit        # zsh
# fish aliases inherit completions automatically

rsmultigit could also be extended to take a program name: e.g. rsmultigit complete bash --name mg would emit completions bound to mg. Not currently implemented — the complete subcommand hardcodes "rsmultigit" in cli::print_completions.

Top-level help_template and subcommand heading interaction

The top-level Cli uses a custom help_template containing a literal Commands: line above {subcommands}. If subcommand help_heading support ever lands, the template needs to drop that literal — otherwise you’d see Commands: above clap’s auto-emitted per-group headings. Flagging it here so it’s not forgotten.

--version vs version subcommand

Both exist. --version is the clap-derived flag and prints a one-line rsmultigit x.y.z by Author. The version subcommand prints the richer version block with git SHA / branch / dirty / rustc / build timestamp (populated by build.rs). Keep both — they serve different use cases (scripts that parse a version string vs humans debugging an install).

Global flags on subcommands

--terse, --no-header, --no-output, --verbose, --print-not, --no-stop, -j/--jobs are all declared with global = true on the top-level Cli, so they can appear before or after the subcommand:

rsmultigit --jobs 8 pull           # works
rsmultigit pull --jobs 8            # also works

Subcommand-specific flags (e.g. pull --quiet, grep -l) are declared on the subcommand variant and only work after the subcommand name. That split is intentional and matches git’s own conventions.