Add --exclude-ref-prefix to trim namespaces from --all-refs · Entire

Add --exclude-ref-prefix to trim namespaces from --all-refs

ee37983→main·

Soph·2mo ago·16 files·+256 added/-54 removed

GitHub's refs/pull/* namespace is the load-bearing case: every PR ever opened against an open-source repo contributes a refs/pull/N/head that points at a commit in someone's fork. --all-refs against a busy repo (kubernetes ~120k PRs, react ~17k PRs) drags all of those into the target, even when the fork is long gone.

--exclude-ref-prefix subtracts namespaces from auto-discovery and prune scope. Excluded refs are left alone entirely: not pulled from source, not pushed to target, not pruned from target. Explicit --map values override the filter, since they're explicit user intent.

Common shape:

git-sync sync --all-refs --exclude-ref-prefix refs/pull/ <src> <tgt>

The flag is repeatable across all sync-like commands plus probe and fetch. ExcludeRefPrefixes is also exposed on RefScope (and on ProbeRequest for probe-only callers) at the library level.

Implementation: a small IsRefExcluded helper in planner gates four sites — the branch walk, the tag/other walk, addPruneCandidates, and replicateCanBootstrap's prune-shortcut check. The wildcard filter applies in BuildDesiredRefs' three auto-discovery paths; the Mappings path bypasses it by construction. Wire-level ls-refs still requests "refs/" under AllRefs (the wire protocol's prefix arg is include-only), and the filter applies client-side.

Tests:

Docs: usage.md walks through the GitHub use case and the subtract-from-auto-discovery semantics.

Sessions

Changes

16

CLI usage

You can use the command like this:

git-sync sync \
  --all-refs \
  --exclude-ref-prefix refs/pull/ \
<source-url> \
<target-url>

Additionally, --exclude-ref-prefix subtracts from auto-discovery (branches, tags, and --all-refs namespaces) and from prune scope, so excluded refs are left alone entirely: not pulled from source, not pushed to target, not pruned from target.