# Wire --all-refs into the CLI surface

`07d05d5`→[main](/content/gh/entireio/git-sync/commits/main/index.html)·Soph·2mo ago·7 files·+48 added/-1 removed

Adds --all-refs to sync, plan, replicate, bootstrap, fetch, and probe.
For sync/plan/replicate/bootstrap the flag bundles AllRefs scope with
BestEffort policy: the broader ref discovery only earns its keep when
hidden-ref refusals downgrade to warnings instead of tanking the run.
Probe and fetch get AllRefs as scope-only (neither pushes), with a
tailored flag description so the help text doesn't lie about
"warnings".

The unstable BootstrapRequest grows a BestEffort field so the CLI's
RunE can mirror the sync-side coupling. Library callers keep the two
halves decoupled via RefScope.AllRefs and SyncPolicy.BestEffort.

docs/usage.md documents the --all-refs example, the strict/best-effort
split, and adds "warned" to the JSON output keys list.

## Sessions

011ba13b7e3d View transcript

[?\
do we have integration tests? Claude Code·Opus 4.7·1 step](/content/gh/entireio/git-sync/session/d0406407-d612-489d-b375-1372d062af82#timeline-011ba13b7e3d/index.html)

## Changes

7

- cmd/git-sync

- Mbootstrap.go+4

- Mfetch.go+1

- Mflags.go+10

- Mprobe.go+1

- Msyncplan.go+4

- docs

- Musage.md+23/-1

- unstable

- Mclient.go+5

```  
28 unmodified lines
```

SilenceUsage:  true,
RunE: func(cmd *cobra.Command, args []string) error {
    req.Protocol = gitsync.ProtocolMode(protocolVal)
    if req.Scope.AllRefs {
        req.BestEffort = true
    }

if req.Source.URL == "" && len(args) > 0 {
        req.Source.URL = args[0]
    }
}

cmd.Flags().StringVar(&branches, "branch", "", "comma-separated branch list; default is all source branches")
cmd.Flags().StringArrayVar(&mappings, "map", nil, "ref mapping in src:dst form; short names map branches, full refs map exact refs")
cmd.Flags().BoolVar(&req.IncludeTags, "tags", false, "mirror tags")
allRefsFlag(cmd, &req.Scope.AllRefs)
cmd.Flags().BoolVar(&req.Options.CollectStats, "stats", false, "print transfer statistics")
cmd.Flags().BoolVar(&req.Options.MeasureMemory, "measure-memory", false, "sample elapsed time and Go heap usage")
cmd.Flags().BoolVar(&req.Options.Progress, "progress", false, "show live per-side throughput on stderr (TTY only)")
```

Mcmd/git-sync/bootstrap.go+4
```

```  
68 unmodified lines
```

cmd.Flags().StringVar(&branches, "branch", "", "comma-separated branch list; default is all source branches")
cmd.Flags().BoolVar(&req.IncludeTags, "tags", false, "include tags in the fetch request")
cmd.Flags().BoolVar(&req.Scope.AllRefs, "all-refs", false, "include every refs/* on the source (notes, pulls, custom namespaces) in the fetch request")
addProtocolFlag(cmd, &protocolVal)
cmd.Flags().BoolVar(&req.Options.CollectStats, "stats", false, "print transfer statistics")
cmd.Flags().BoolVar(&req.Options.MeasureMemory, "measure-memory", false, "sample elapsed time and Go heap usage")
```

Mcmd/git-sync/fetch.go+1
```

```  
45 unmodified lines
```

cmd.Flags().Var(mode, "protocol", "protocol mode: auto, v1, or v2")

// allRefsFlag registers --all-refs. The CLI semantic is "mirror everything
// from source on a best-effort basis" — callers must propagate AllRefs to
// BestEffort inside RunE after flag parsing (cobra has no on-set hook), so
// per-ref rejections become warnings on top of the broader scope.
func allRefsFlag(cmd *cobra.Command, allRefs *bool) {
    cmd.Flags().BoolVar(allRefs, "all-refs", false,
        "mirror every refs/* on the source (notes, pulls, custom namespaces) on a best-effort basis; "+
        "per-ref server rejections become warnings rather than failing the sync")
}

func newProtocolFlag() protocolModeFlag {
    return protocolModeFlag(protocolMode(envOr("GITSYNC_PROTOCOL", validation.ProtocolAuto)))
}
```

Mcmd/git-sync/flags.go+10
```

```  
64 unmodified lines
```

addTargetAuth(cmd, &targetAuth)

cmd.Flags().BoolVar(&req.IncludeTags, "tags", false, "include tag ref prefixes in probe")
cmd.Flags().BoolVar(&req.AllRefs, "all-refs", false, "advertise all refs/* prefixes (notes, pulls, custom namespaces) in the probe")
addProtocolFlag(cmd, &protocolVal)
cmd.Flags().BoolVar(&req.Options.CollectStats, "stats", false, "print transfer statistics")
cmd.Flags().BoolVar(&req.Options.MeasureMemory, "measure-memory", false, "sample elapsed time and Go heap usage")
```

Mcmd/git-sync/probe.go+1
```

```  
42 unmodified lines
```

RunE: func(cmd *cobra.Command, args []string) error {
    req.Policy.Mode = gitsync.OperationMode(modeValue)
    req.Policy.Protocol = gitsync.ProtocolMode(protocolVal)
    if req.Scope.AllRefs {
        req.Policy.BestEffort = true
    }

if req.Source.URL == "" && len(args) > 0 {
        req.Source.URL = args[0]
    }
}

cmd.Flags().BoolVar(&req.Policy.IncludeTags, "tags", false, "mirror tags")
cmd.Flags().BoolVar(&req.Policy.Force, "force", false, "allow non-fast-forward branch updates and retarget tags")
cmd.Flags().BoolVar(&req.Policy.Prune, "prune", false, "delete managed target refs that no longer exist on source")
allRefsFlag(cmd, &req.Scope.AllRefs)
cmd.Flags().BoolVar(&req.Options.CollectStats, "stats", false, "print transfer statistics")
cmd.Flags().BoolVar(&req.Options.MeasureMemory, "measure-memory", false, "sample elapsed time and Go heap usage")
cmd.Flags().BoolVar(&req.Options.Progress, "progress", false, "show live per-side throughput on stderr (TTY only)")
```

Mcmd/git-sync/syncplan.go+4
```

```  
154 unmodified lines
```

Mirror every ref namespace (notes, pulls, custom) on a best-effort basis:

```bash
git-sync sync \
  --all-refs \
  <source-url> \
  <target-url>
```

`--all-refs` broadens the source ref discovery from `refs/heads/`+`refs/tags/`
to every `refs/*` namespace and lets ref mappings target arbitrary
namespaces (`refs/notes/*`, `refs/pull/*`, custom refs). It also turns on
best-effort failure handling: when the target's `receive-pack` rejects an
individual ref (e.g. GitHub refusing writes to `refs/pull/*` hidden refs),
the rejected ref appears in the result with `action=warn` and the server's
reason instead of failing the whole sync. Pack-level transport or unpack
failures remain fatal.

Library callers can decouple the two halves: `RefScope.AllRefs` controls
scope alone, and `SyncPolicy.BestEffort` controls failure handling. The
CLI bundles them under `--all-refs` for convenience.

Force source-side protocol v2:

```bash

11 unmodified lines

- keys use `camelCase`
- refs and hashes are serialized as strings, not raw byte arrays
- top-level keys include `plans`, `pushed`, `skipped`, `blocked`, `deleted`, `dryRun`, `protocol`, and `stats`, plus `relay`, `relayMode`, `relayReason`, `batching`, `batchCount`, `plannedBatchCount`, and `tempRefs`
- each item in `plans` includes stable string fields such as `branch`, `sourceRef`, `targetRef`, `sourceHash`, `targetHash`, `kind`, `action`, and `reason`

## Auth
