Skip to content

git-remote-entire: actionable hint when the cluster host is missing#1649

Open
Soph wants to merge 1 commit into
mainfrom
soph/git-remote-missing-host-hint
Open

git-remote-entire: actionable hint when the cluster host is missing#1649
Soph wants to merge 1 commit into
mainfrom
soph/git-remote-missing-host-hint

Conversation

@Soph

@Soph Soph commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

https://entire.io/gh/entireio/cli/trails/768

Problem

git clone entire://gh/entire.io/cli parses gh into the host slot (net/url gives Host="gh", Path="/entire.io/cli"), so the git remote helper sailed past URL validation and later died at cluster discovery with an opaque https://gh/.well-known/entire-cluster.json error. The empty-host form (entire:///gh/...) hit only a bare fatal: missing host in URL message.

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:

fatal: entire:// URL is missing its cluster host ("gh" is a forge id, not a host).
The full form is entire://<cluster-host>/gh/<owner>/<repo>.
To pick a mirror interactively, run:

    entire repo clone /gh/entire.io/cli

When the shorthand isn't recoverable (bare entire://, non-forge leading segment), it falls back to the original missing host error.

Why this layer

git clone entire://... invokes the helper directly via git's remote-helper protocol — it never routes through entire 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 clone resolves 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.IsSupportedForge predicate (today only gh), so a future forge (e.g. et) picks up the hint automatically once it's in the forge map.

Testing

  • New TestMissingClusterHostMessage table test: forge-in-host, empty-host-with-forge-path, and three fall-back cases.
  • mise run check green (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-entire now fails fast when an entire:// 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—suggests entire repo clone <shorthand> for the interactive mirror picker. Unrecoverable inputs (bare entire://, unknown leading path segment, incomplete path) keep the original missing-host message.

Detection reuses gitremote.IsSupportedForge. TestMissingClusterHostMessage covers forge-in-host, empty-host-with-forge path, and fallback cases.

Reviewed by Cursor Bugbot for commit 317808c. Configure here.

Copilot AI review requested due to automatic review settings July 6, 2026 13:25
@Soph Soph requested a review from a team as a code owner July 6, 2026 13:25

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ 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)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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/&lt;owner&gt;/&lt;repo&gt; 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.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 317808c. Configure here.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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/clusterHostHint helpers 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.

Comment on lines +226 to +233
// 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)
}
Comment on lines +184 to +195
{
// 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
@Soph Soph force-pushed the soph/git-remote-missing-host-hint branch from 317808c to 115fccb Compare July 6, 2026 13:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants