Scaffolder generate project git push¶
Status: APPROVED — GTB-parity gap from the v0.22.0 audit (Phase 2,
§A). RTB already does git-init + an initial conventional commit
(commands/generate/project.rs:254, gated by --no-git), but stops
there — no remote, no push, no existing-repo detection. GTB
(internal/generator/gitinit.go) does the full sequence. No open design
decisions (mechanism mirrors GTB; transport reuses rtb-vcs).
1. Surface¶
rtb generate project <name> [--no-git]
[--git-branch <name>] # default: main
[--push] [--remote <url>]
--no-git(existing) → skip all git work.--git-branch→ initial branch name (defaultmain); today RTB's initial branch is implicit.--push→ after the initial commit, addoriginand push.--remote <url>→ explicit origin URL; if omitted with--push, derive from the project name + a configured default host (best-effort; a non-derivable remote is a clear error, not a panic).
2. Mechanism¶
Mirrors GTB gitinit.go, RTB-idiomatically via rtb-vcs (the
git/init.rs / git/commit.rs / git/push.rs modules already exist —
push.rs:48 is the unused capability this spec wires up):
- Existing-repo detection — if the destination is already inside a
git work-tree (
gixdiscovery walking ancestors), skip init and log it (don't nest a repo). GTB does this (gitinit.go:51). - Init at
--git-branch(configure the initial branch name rather than relying on the git default). - Author resolution — use the host git identity
(
user.name/user.email) when present; fall back to a neutral scaffolder identity for the initial commit so it never fails on an unconfigured machine (GTBgitinit.go:162). - Initial commit (existing behaviour, retained).
- Push (when
--push): createoriginfrom--remote/derived URL, push--git-branch. All push steps are best-effort/non-fatal — a push failure warns and leaves a fully-initialised local repo (GTB's posture: scaffolding succeeded even if the remote isn't reachable yet).
3. Security / validation¶
--remoteURL validated: NFC-normalise, reject control chars, enforce a scheme allowlist consistent with rtb-vcs clone (https/ssh/git@forms), length cap. No shell interpolation —rtb-vcsdrives the transport, not a spawnedgit.- Derived remote URLs are built from the already-validated project name + a configured host constant; never from raw user free-text.
4. Testing (TDD)¶
- Unit: branch-name + remote-URL validation (accept good, reject control/over-length/bad-scheme); remote derivation from name+host; existing-repo detection short-circuits init.
- E2E (
assert_cmd, hermetic — local bare-repo fixture as the remote):generate project --push --remote file://<bare>pushes the initial commit;--git-branch devlands ondev; generating inside an existing repo skips init (no nested.git); a push to an unreachable remote warns + exits 0 with a valid local repo;--no-gitunchanged.
5. Out of scope¶
- Creating the remote repository via a forge API (rtb-vcs
ReleaseProvidercould latercreate_repo, but this spec only pushes to an existing remote). - Multi-remote / upstream-fork setups.