Expand description
Honest transfer-progress reporting for clone/push/pull/fetch
(#711).
mkit clone/push/pull/fetch previously printed only a start
banner and a final summary — the network transfer itself was silent.
This module adds a lightweight, thread-local progress sink that the
transfer call chain (push_branch_with_depth in
remote_dispatch::mod, unpack_downloaded_packs in
remote_dispatch::packmap) reports real, already-happened work to:
objects staged into the outgoing pack, bytes handed to the transport,
and objects unpacked from a downloaded pack.
It deliberately never reports git’s fabricated
Enumerating/Counting/Compressing objects or Total N (delta D)
lines — mkit’s transport is one-object-per-pack and computes no
cross-branch delta graph, so those numbers would be invented (see
docs/PARITY.md’s “Human-facing output parity” section).
§Threading pattern
Rather than adding a progress parameter to every function in the
push_all_with → push_branch_with_depth → pull_all →
fetch_objects call chain (touching dozens of existing call sites,
including many integration tests that don’t care about progress at
all), this mirrors the pattern already used for interrupt handling:
crate::signal::is_shutdown() is a global checkpoint polled inside
the same loops. Here, report is the equivalent checkpoint — a
thread-local sink installed by start and torn down by the
returned Guard’s Drop. When no sink is installed (the common
case: every test that doesn’t call start, and any non-interactive
run), report is a cheap thread-local check that does nothing.
Concurrent callers (see fetch_pull_lock_scope.rs, which fetches
from multiple threads) are unaffected: the sink is thread-local, so
each thread has its own (absent, by default) reporter.
§Interactivity gating
Mirrors term::use_color_stderr’s tty auto-detection: progress is
shown only when stderr is a tty, unless overridden by an explicit
--quiet flag (forces off) or the MKIT_PROGRESS env var
(always/never/auto, mirroring NO_COLOR/CLICOLOR_FORCE’s
override convention) — always is how the CLI integration tests
observe progress lines over a piped (non-tty) stderr.
Structs§
- Guard
- RAII handle returned by
start. Dropping it flushes a final progress line (if anything was reported) and uninstalls the thread-local sink, so a command can simply hold the guard for the duration of its transfer call and let scope-exit (including an earlyreturnon error) clean up.
Enums§
- Event
- One real, already-happened unit of transfer work. Never a projection or estimate.
Functions§
- report
- Report one real unit of already-completed transfer work to the
current thread’s installed reporter, if any. A no-op — a single
thread-local check — when no
Guardis active on this thread, which is the default for every caller that doesn’t opt in (including every existing test that drivespush_branch_with_depth/push_all/pull_all/fetch_alldirectly). - should_
report - Whether progress should be shown on stderr: not explicitly silenced
(
--quiet/-q), and eitherMKIT_PROGRESSforces a decision or stderr is a tty. Mirrorsterm::use_color_stderr’sNO_COLOR/CLICOLOR_FORCE-style override convention —alwaysis how CLI integration tests observe progress lines over a piped (non-tty) stderr;neveris an explicit opt-out distinct from--quiet(e.g. for scripting environments that set it once instead of threading--quietthrough every call site). - start
- Install a thread-local progress reporter for the duration of the
returned
Guard.enabled = falseinstalls no reporter, soreportstays a cheap no-op — used when stderr isn’t interactive or--quietwas passed (seeshould_report).