girt-cli 0.2.1

Command-line tool for inspecting and benchmarking Git repositories with girt
girt-cli-0.2.1 is not a library.

girt-cli

girt is a command-line tool for inspecting, comparing and benchmarking Git repositories with the girt library. It is not a replacement for Git: it exposes what the library does today, under names that follow girt's concepts rather than Git's plumbing commands.

cargo install girt-cli
girt repo info
girt log --limit 5
girt diff --patch v1 main

Output

Default output is line-oriented and meant for both people and scripts: full object IDs, one record per line, stable field order. --git makes a command print exactly what its Git equivalent prints, so the two tools can be diffed:

diff <(girt --git tree list --recursive HEAD) <(git ls-tree -r HEAD)
hyperfine 'girt object batch --check < ids' 'git cat-file --batch-check < ids'

tests/git_parity.rs checks these pairings against git in a scratch repository.

girt Git equivalent for --git
repo info git rev-parse --git-dir --git-common-dir --show-toplevel --is-bare-repository --show-object-format
init git init
object id / hash / show / info / cat / exists / batch git rev-parse --verify / hash-object / cat-file -p / -t, -s / raw / -e / --batch
object list / count git cat-file --batch-all-objects --batch-check / git count-objects -v
tree list git ls-tree
ref list / show / set / delete / log git for-each-ref / rev-parse / update-ref / update-ref -d / reflog show
log git log
history count / merge-base / contains git rev-list --count / merge-base / merge-base --is-ancestor
diff / --renames / --patch git diff-tree -r --name-status / -M / git diff
index list git ls-files
status git status --porcelain
ignore check git check-ignore -v
checkout git read-tree -um (HEAD does not move)
worktree list git worktree list
config get / list git config --get / --list
remote list / heads git remote -v / git ls-remote
clone / fetch / push no --git output
pack verify / reindex, maintenance git index-pack for reindex only

Color

The global --color auto|always|never option controls help, diagnostics and human output. The default, auto, decides separately for stdout and stderr: a non-empty NO_COLOR disables color, then a non-empty CLICOLOR_FORCE other than 0 forces it, then CLICOLOR=0 disables it. Otherwise, color requires a terminal and TERM other than dumb. An explicit always or never overrides the environment.

Status uses green for staged changes and red for unstaged and untracked changes. Patches use bold headers, cyan hunk headers, green additions and red deletions; log IDs are yellow. --git output remains uncolored even with --color always. Color settings do not change when progress is displayed.

Live progress

Clone, fetch, push and checkout show live phases and available object counts on stderr when it is connected to a terminal. Known totals include percentages; server messages appear as remote: lines. Redraws are limited to about ten per second, with a final line for each phase. Checkout counts include file and directory operations. Standard output keeps its existing record format.

Use -q or --quiet to suppress progress, including server progress messages. --git also suppresses progress, as does redirecting stderr (for example, 2>transfer.log). Errors and explicitly requested logging remain available.

Pack verification, reindexing and maintenance show elapsed activity and final report totals where available. The library does not yet expose their intermediate counters or network byte counters, so these phases do not show invented percentages or throughput. Remaining hooks are tracked in the progress counter issue.

girt clone https://github.com/joshka/girt
girt --quiet fetch
girt checkout HEAD 2>checkout.log

Shell completion

Add one line to your shell's startup file. Tab then completes commands, options and values read from the current repository: revisions and ref names, remote names, linked worktree names and config keys.

source <(girt completions zsh)     # ~/.zshrc
source <(girt completions bash)    # ~/.bashrc
girt completions fish | source     # ~/.config/fish/config.fish

The script is a small hook that calls back into girt on each Tab, so completions stay in step with the installed version. Completing a value reads only refs, config and worktree registrations, never objects; outside a repository it offers no values. -C <path> is not applied while completing. girt completions also supports elvish and powershell, and COMPLETE=<shell> girt prints the same script.

Packagers who need a fixed file can use girt completions --static <shell>, which completes commands and options but not repository values.

Man pages

girt man prints girt.1. girt man --out <dir> writes girt.1 and one page per subcommand (girt-object.1, girt-object-show.1, ...) for installing into a man1 directory:

girt man --out ~/.local/share/man/man1
man girt-diff

Errors and logging

Errors print as color-eyre reports. -v, -vv and -vvv log girt's tracing spans to stderr; at debug level the active spans are also captured in error reports. GIRT_LOG takes EnvFilter directives (for example GIRT_LOG=girt=debug) and overrides -v; an invalid value is an error. RUST_LOG is not read, so filters set for other tools don't affect girt.

Limits

These come from the library and are listed in each command's --help:

  • Revisions use Git's syntax (main~2, v1^{tree}, HEAD:path, main@{1}, @{u}, @{push}), and log and history count take ranges (A..B, A...B, ^A). Pseudo-references other than HEAD (such as ORIG_HEAD), dated reflog selectors, @{-N}, :path index lookups and :/text searches are refused. See the library's revision module.
  • Ranges walk the excluded side's whole history, unlike Git, which stops early, so log A..B near the root of a long history is slower than Git.
  • Revisions accept unique hexadecimal prefixes of at least four digits. Ref names take precedence over short IDs; Git's ambiguous-name warning is not reproduced.
  • Abbreviated IDs honor core.abbrev (automatic by default) and lengthen collisions across loose objects, indexed packs and alternates. Unindexed packs and promised objects not present locally do not participate. Each output operation retains loose buckets as they are first inspected; concurrent writes can invalidate a previously unique abbreviation.
  • status and checkout compare raw bytes on macOS and Linux: no attributes, filters, EOL conversion or core.filemode. macOS paths must be ASCII. checkout drops derived index caches, including fsmonitor and untracked caches, for Git to rebuild. Split/sparse indexes, resolve-undo data and unknown extensions are refused.
  • diff --patch uses a plain Myers diff, so ambiguous hunks can align differently from Git.
  • clone, remote heads, fetch and push support SSH on macOS/Linux using system OpenSSH: ssh://[user@]host[:port]/path or [user@]host:path. Normal SSH config, identities, agents and host trust apply. Command selection is GIT_SSH_COMMAND, core.sshCommand, GIT_SSH, then ssh on PATH. Configured command strings execute through the shell, so trust the configuration. Terminal prompts/job control are unavailable; use an agent or askpass. Non-OpenSSH variants, percent-encoded SSH URLs, query/fragment fields and paths starting with ~ are unsupported.
  • HTTP(S) clone and remote heads still use anonymous access, without credential helpers. fetch and push use the library's configured credential helpers, including store; they decline interactive credential prompts. Adding helpers to clone/discovery requires sharing the workflow adapter's helper selection and authentication retry policy.
  • object count --git omits Git's garbage and size-garbage lines: girt does not classify stray files in object directories. An .idx without its .pack fails opening instead of counting as garbage. Multi-pack indexes are not read, so object list and count see only .idx packs.
  • maintenance run deletes data. It requires --yes, and no other process may use the repository while it runs.