fix(git): non-interactive clones (no hang, #104) + blobless partial clone for speed (#91)#108
Merged
Merged
Conversation
…t instead of hanging
When cloning a private repo with no usable credentials, git fell back to an
interactive terminal prompt ("Username for 'https://...':"). capa never answers
it, so `capa install` hung indefinitely instead of reporting that the repo is
inaccessible.
Force git to run non-interactively in the central git() wrapper, so every
clone/fetch (skills, rules, hooks, plugins, registries) fails fast and the error
is surfaced to the user:
- GIT_TERMINAL_PROMPT=0 — no interactive HTTP(S) credential prompt
- GCM_INTERACTIVE=never — no Git Credential Manager GUI/browser prompt
- GIT_SSH_COMMAND=ssh -o BatchMode=yes -o ConnectTimeout=10 (defensive; a
user-set GIT_SSH_COMMAND still wins) — SSH fails fast instead of prompting
A caller-supplied opts.env still overrides these defaults.
Also improve explainGitError(): recognise git's "terminal prompts disabled"
(and "could not read Password") output and, for the no-auth case, tell the user
the repo is private/inaccessible and to connect the integration — while keeping
the "authentication failed"/"not accessible" substrings install-one-skill keys
off to append the integrations link.
Tests: assert the non-interactive env is passed (and is overridable), and cover
explainGitError's prompt-disabled / no-auth / token / not-found / network cases.
Closes #104
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Type the mock's opts param as `object` and cast at the use site (matching the existing windowsHide test) so the cast to `typeof execFile` is valid without an intermediate `unknown`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ed up big-repo installs `git clone --mirror` downloads every blob across all history, which is slow on large repos (e.g. remotion). Switch to a blobless partial clone: fetch the full commit/tree graph (so any SHA/tag/branch still resolves offline in resolveRef) but skip historical file contents. The blobs for the single revision we check out are fetched lazily by `git worktree add` during materializeSnapshot, so the snapshot tree stays byte-identical and no consumer is affected. Why blobless rather than the sparse-checkout-per-file approach from #91: consumers walk whole trees (`@`-basename search for skills/rules/hooks/plugins) and copy entire skill directories that reference sibling files, so the full file set isn't known up front. Blobless keeps the materialized tree complete while still skipping the expensive history — the speedup without the regression risk the issue itself cautions about. Requires git >= 2.19; servers without partial-clone support degrade gracefully to a full clone (git warns and ignores the filter), so there's no regression on older transports (verified: file:// fixtures still materialize completely). Closes #91. Tests: a real-git regression guard that cloning via ensureMirrorClone then materializing still yields every file, plus an assertion that the clone is issued with --filter=blob:none immediately after --mirror. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #104 and #91. Two related improvements to repository cloning.
1. Private-repo installs fail fast instead of hanging (#104)
Problem
Cloning a private repo with no usable credentials made
capa installhang forever: git fell back to an interactive terminal prompt (Username for 'https://...':) that capa never answers.Fix
Force git non-interactive in the central
git()wrapper, so every clone/fetch (skills, rules, hooks, plugins, registries) fails fast and the error is surfaced:GIT_TERMINAL_PROMPT=0— no interactive HTTP(S) credential promptGCM_INTERACTIVE=never— no Git Credential Manager GUI/browser popupGIT_SSH_COMMAND=ssh -o BatchMode=yes -o ConnectTimeout=10— defensive; a user-set value still winsA caller-supplied
opts.envstill overrides these.explainGitError()now recognises git'sterminal prompts disabledoutput and, for the no-auth case, tells the user the repo is private/inaccessible and to connect the integration.2. Blobless partial clone for faster big-repo installs (#91)
Problem
git clone --mirrordownloads every blob across all history — slow on large repos (e.g. remotion).Fix
Switch the mirror clone to a blobless partial clone (
--filter=blob:none): fetch the full commit/tree graph (so any SHA/tag/branch still resolves offline inresolveRef) but skip historical file contents. The blobs for the single revision we actually check out are fetched lazily bygit worktree addduringmaterializeSnapshot, so the snapshot tree stays byte-identical and no consumer is affected.Why not the sparse-checkout-per-file approach from the issue? Consumers walk whole trees (
@-basename search for skills/rules/hooks/plugins) and copy entire skill directories that reference sibling files — the full file set isn't knowable up front. Blobless keeps the materialized tree complete while still skipping the expensive history: the speedup without the regression risk the issue explicitly cautions about (skills/rules/hooks/plugins must not regress).Safety:
file://fixtures, which still materialize completely.Verification
worktree addmaterializes every file at the revision.explainGitErrorprompt-disabled/no-auth/token/not-found/network cases; blobless clone issues--filter=blob:noneand still materializes a complete snapshot.bunx tsc --noEmitclean; full suite 1048 pass / 0 fail.🤖 Generated with Claude Code