git-remote-entire: actionable hint when the cluster host is missing#1649
git-remote-entire: actionable hint when the cluster host is missing#1649Soph wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 317808c. Configure here.
| func missingClusterHostMessage(parsedURL *url.URL, rawURL string) string { | ||
| // Forge id in the host slot: the shorthand is /<host><path>. | ||
| if gitremote.IsSupportedForge(parsedURL.Host) { | ||
| return clusterHostHint(parsedURL.Host, "/"+parsedURL.Host+parsedURL.Path) |
There was a problem hiding this comment.
Incomplete URL still suggests clone
Medium Severity
When the parsed entire:// URL has a known forge id in the host slot (e.g. entire://gh with no owner/repo path), missingClusterHostMessage always calls clusterHostHint and suggests entire repo clone /gh. That shorthand does not satisfy parseMirrorCloneRef’s required gh/<owner>/<repo> shape, so users get a “helpful” command that fails immediately. The empty-host case for a lone /gh path correctly falls back to the generic missing-host error, so the two equivalent mistakes are handled inconsistently.
Reviewed by Cursor Bugbot for commit 317808c. Configure here.
There was a problem hiding this comment.
Pull request overview
This PR improves git-remote-entire URL validation so that git clone entire://... fails fast with an actionable stderr hint when the cluster host is missing—especially the common case where a forge id (e.g. gh) is parsed into the URL host slot.
Changes:
- Extend URL validation to treat empty host or a supported forge id in the host slot as “missing cluster host”, emitting a guided hint toward
entire repo clone /gh/<owner>/<repo>. - Add
missingClusterHostMessage/clusterHostHinthelpers to centralize the new messaging. - Add unit tests covering the new message behavior and fallbacks.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| cmd/git-remote-entire/main.go | Adds forge-aware “missing cluster host” handling and actionable hint rendering. |
| cmd/git-remote-entire/main_test.go | Adds table tests for the new missing-cluster-host message and fallback cases. |
| // Forge id in the host slot: the shorthand is /<host><path>. | ||
| if gitremote.IsSupportedForge(parsedURL.Host) { | ||
| return clusterHostHint(parsedURL.Host, "/"+parsedURL.Host+parsedURL.Path) | ||
| } | ||
| // Empty host with a forge-led path: the path is already the shorthand. | ||
| if forge, _, ok := strings.Cut(strings.TrimPrefix(parsedURL.Path, "/"), "/"); ok && gitremote.IsSupportedForge(forge) { | ||
| return clusterHostHint(forge, parsedURL.Path) | ||
| } |
| { | ||
| // The motivating case: forge id typed where the cluster host belongs. | ||
| name: "forge id in host slot points at repo clone", | ||
| rawURL: "entire://gh/entire.io/cli", | ||
| contains: []string{"missing its cluster host", `"gh" is a forge id`, "entire repo clone /gh/entire.io/cli"}, | ||
| }, | ||
| { | ||
| // Empty host but the path already reads as a forge shorthand. | ||
| name: "empty host with forge path points at repo clone", | ||
| rawURL: "entire:///gh/entire.io/cli", | ||
| contains: []string{"missing its cluster host", "entire repo clone /gh/entire.io/cli"}, | ||
| }, |
`git clone entire://gh/entire.io/cli` parses `gh` into the host slot, so
the helper previously failed at cluster discovery with an opaque
`https://gh/.well-known/...` error. The empty-host form
(`entire:///gh/...`) hit only a bare "missing host" message.
Detect both shapes in the URL-validation switch: when the host is empty
or is a known forge id (`gitremote.IsSupportedForge`), print a message
that names the problem and points at the interactive mirror picker, e.g.
entire repo clone /gh/entire.io/cli
This reuses the existing actionable-error idiom (`fatalMessage`) and
keeps the helper a dumb transport — no TTY/stdin/stdout involvement, and
safe in CI (stderr line + exit 128, never a hang). The picker lives in
`entire repo clone`, the right layer, because it clones a fully-qualified
URL so later fetches don't re-prompt.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: acbb7200e503
317808c to
115fccb
Compare


https://entire.io/gh/entireio/cli/trails/768
Problem
git clone entire://gh/entire.io/cliparsesghinto the host slot (net/urlgivesHost="gh",Path="/entire.io/cli"), so the git remote helper sailed past URL validation and later died at cluster discovery with an opaquehttps://gh/.well-known/entire-cluster.jsonerror. The empty-host form (entire:///gh/...) hit only a barefatal: missing host in URLmessage.In both cases the user simply omitted the cluster host — and the CLI already has an interactive mirror picker for exactly this (
entire repo clone /gh/entire.io/cli), but nothing pointed them at it.Change
Extend the URL-validation switch in
cmd/git-remote-entire/main.go: when the host is empty or is a known forge id (gitremote.IsSupportedForge), print an actionable message that names the problem and points at the picker:When the shorthand isn't recoverable (bare
entire://, non-forge leading segment), it falls back to the originalmissing hosterror.Why this layer
git clone entire://...invokes the helper directly via git's remote-helper protocol — it never routes throughentire repo clone, so the helper is the only place that sees this input. A picker can't live in the helper itself: stdin/stdout are reserved for git's pkt-line stream, and the helper can't rewrite the stored remote URL, so it would re-prompt on every future fetch.entire repo cloneresolves the mirror once and clones a fully-qualified URL — the right home for the picker. This reuses the existing actionable-error idiom (fatalMessage) and stays a dumb transport: stderr line + exit 128, safe in CI, no hang.Detection keys off the shared
gitremote.IsSupportedForgepredicate (today onlygh), so a future forge (e.g.et) picks up the hint automatically once it's in the forge map.Testing
TestMissingClusterHostMessagetable test: forge-in-host, empty-host-with-forge-path, and three fall-back cases.mise run checkgreen (fmt + lint + unit + integration + e2e canary).🤖 Generated with Claude Code
Note
Low Risk
Changes are limited to URL validation stderr messaging and exit 128; no auth, transport, or git helper protocol behavior is altered.
Overview
git-remote-entirenow fails fast when anentire://URL has no cluster host, including the case where a forge id (e.g.gh) lands in the host slot because of URL parsing (entire://gh/owner/repo).Instead of a generic missing-host line or a later opaque discovery error against
https://gh/..., stderr explains that the cluster host is missing, shows the full URL shape, and—when a forge shorthand can be recovered—suggestsentire repo clone <shorthand>for the interactive mirror picker. Unrecoverable inputs (bareentire://, unknown leading path segment, incomplete path) keep the original missing-host message.Detection reuses
gitremote.IsSupportedForge.TestMissingClusterHostMessagecovers forge-in-host, empty-host-with-forge path, and fallback cases.Reviewed by Cursor Bugbot for commit 317808c. Configure here.