GitGateUpstream carries each entry's extra_hosts; a new
git_gate_aggregate_extra_hosts() merges them into one map for the
gate container's /etc/hosts. Same host -> same IP is harmless
duplication; same host -> different IPs is a manifest bug
(/etc/hosts is per-container, not per-upstream) and dies with
the conflicting upstream names.
DockerGitGate.start passes one --add-host host:ip per merged
entry on docker create. Empty map (the default) emits no flags
and is a no-op for bottles that don't need DNS overrides.
The gate is now a transparent mirror, not push-only. Per-repo
init now runs `git remote add --mirror=fetch origin <url>` so a
later `git fetch origin` mirrors the upstream's full ref graph at
canonical paths. The pre-receive hook forwards accepted refs via
`git push origin` (renamed from upstream).
New: an access-hook script wired via `git daemon --access-hook`
runs `git fetch origin --prune` against the real upstream before
every upload-pack request (clone, fetch, pull, ls-remote). On
upstream error the hook exits non-zero — the agent's fetch fails
rather than the gate serving stale data.
The pre-existing smoke test (ls-remote against unreachable
upstream returns refs) had to invert: under the bidirectional
design any ls-remote success is necessarily a success against
the upstream, so the unreachable-upstream case now correctly
fails closed.
Dockerfile.git-gate builds a small alpine image with git,
openssh-client, and gitleaks; the directory layout the entrypoint
and per-upstream cp's expect is pre-created in the image so docker
cp can target paths beneath /etc/git-gate and /git-gate/creds at
container-create time (cp doesn't create intermediate dirs).
DockerGitGate.start mirrors DockerSSHGate's shape: build, create,
cp the rendered entrypoint + hook + per-upstream identity files
(plus a known_hosts file synthesized from KnownHostKey when set),
attach the egress network, start. build_image gains an optional
dockerfile= argument so the gate can build from its own
Dockerfile in the shared context.
PRD: docs/prds/0008-git-gate.md