Skip to content

fix(bootstrap): compare repo origins transport-agnostically - #11034

Merged
jdx merged 3 commits into
jdx:mainfrom
jeremy:bootstrap-repos-origin-transport
Jul 16, 2026
Merged

jdx merged 3 commits into
jdx:mainfrom
jeremy:bootstrap-repos-origin-transport

Conversation

@jeremy

@jeremy jeremy commented Jul 16, 2026 •

Copy link
Copy Markdown
Contributor

Implements the direction agreed in #10997: [bootstrap.repos] rejected an existing checkout whose origin uses a different transport than the configured url, even when both identify the same repository (e.g. git@github.com:jdx/mise.git vs https://github.com/jdx/mise.git). Updates fetch and pull through the checkout's own origin, so the configured url acts as a repository identity check, not a fetch source.

What changed

origin_matches_config now falls back to comparing a repo_identity for common network URL forms — git@host:path, ssh://user@host[:port]/path, and https://host/path — exactly the three forms from the discussion — reduced to [user@]host[:port]/path with the .git suffix stripped.

Per the contract in the discussion:

  • Still conflicts: different hosts, ssh aliases, explicit ports, and paths.
  • Non-git ssh users stay part of the identity — they can identify different repositories on generic ssh servers. Only the conventional git user is treated as transport metadata.
  • Exact matching preserved for local paths, file:// URLs, Windows paths, and unrecognized syntax (unknown schemes, remote-helper forms).

Docs updated to state the comparison rules.

Tests

  • origin_urls_match_the_same_repo_across_transports: positive ssh↔https coverage across scp, ssh://, suffixless, host-case, same-non-git-user, leading-slash scp paths, and agreeing explicit ports — both directions.
  • origin_urls_conflict_across_hosts_users_ports_and_paths: negative coverage for different host, ssh alias, explicit port, different path/owner, non-git ssh user (scp and url forms), userless ssh (git resolves an omitted user to the login user, not git), query-carrying URLs, http:// and git:// (an insecure transport is never treated as the https config), unrecognized scheme, local vs file://, and Windows paths.
  • status_recognizes_origin_across_transports: real-git fixture through status_one — ssh origin against an https config reports current, a foreign owner reports the unchanged origin does not match configured url conflict.

Also verified against a locally built binary with real fixture repos: all six spellings of the declared repo report current; foreign owner / different host / ssh alias / explicit port / non-git user report conflict; dirty checkouts still hard-stop with has local changes; linked worktrees (.git file) are recognized; repos update (#11022) flows through the same comparison. The released 2026.7.5 binary reports conflict for the ssh-origin case as a control.

Summary by CodeRabbit

  • Bug Fixes
    • Improved repository update checks with transport-agnostic matching across supported remote URL formats (including optional .git, host casing normalization, and explicit port handling).
    • Added stricter conflict detection for mismatches (hosts/users/ports/paths) and for unsupported or insecure/local/file-like URL forms, query/fragment components, and invalid SSH/HTTPS credentials.
    • Updated status behavior to reflect “current” when the configured origin matches the remote identity, otherwise “conflict”.
  • Documentation
    • Expanded “Safe updates only” guidance to define exactly which origin URL variants are treated as equivalent and which are conflicts.

[bootstrap.repos] treated an existing checkout as a conflict when its
origin used a different transport than the configured url, even when
both identify the same repository — e.g. an ssh origin
git@github.com:jdx/mise.git against a configured
https://github.com/jdx/mise.git. Updates fetch and pull through the
checkout's own origin, so the configured url acts as a repository
identity check, not a fetch source.

Normalize common network forms (git@host:path, ssh://git@host/path,
scheme://host/path) to a host/path identity for the comparison.
Different hosts, ssh aliases, explicit ports, and paths still conflict.
Only the conventional git ssh user is treated as transport metadata;
other ssh users can identify different repositories on generic ssh
servers and stay part of the identity. Local paths, file:// urls, and
unrecognized syntax keep exact matching.

Fixes the false conflict discussed in jdx#10997.
Copilot AI review requested due to automatic review settings July 16, 2026 04:25
@coderabbitai

coderabbitai Bot commented Jul 16, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 6eadfa5a-a431-4f70-b55c-4af37970daa1

📥 Commits

Reviewing files that changed from the base of the PR and between 6bb1bff and cdcb6c4.

📒 Files selected for processing (1)
  • src/system/repos.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/system/repos.rs

📝 Walkthrough

Walkthrough

mise now compares recognized Git remote URLs by canonical repository identity across supported transport formats. Tests cover equivalent and conflicting origins, while documentation defines matching behavior for network, local, and file-based URLs.

Changes

Repository origin matching

Layer / File(s) Summary
Canonical origin identity matching
src/system/repos.rs, docs/bootstrap/repos.md
Origin matching parses supported SSH, HTTPS, and scp-like forms, normalizes repository identity components, rejects unsupported variants, and documents equivalent and conflicting URL cases.
Cross-transport matching and conflict tests
src/system/repos.rs
Tests cover symmetric transport matching, .git and slash normalization, host casing, ports, users, local and file URLs, and Current versus Conflict status outcomes.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RepositoryStatus
  participant origin_matches_config
  participant CanonicalRepoIdentity
  RepositoryStatus->>origin_matches_config: compare stored and configured origins
  origin_matches_config->>CanonicalRepoIdentity: parse recognized remote URLs
  CanonicalRepoIdentity-->>origin_matches_config: return canonical repository identity
  origin_matches_config-->>RepositoryStatus: return Current or Conflict
Loading

Poem

A rabbit hops through URLs bright,
SSH and HTTPS align just right.
Hosts and paths are checked with care,
Local trails stay distinct and fair.
“Current!” we cheer beneath the moon.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: transport-agnostic comparison of bootstrap repo origins.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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 [bootstrap.repos] handling by treating a repo’s configured url as an identity check rather than requiring an exact transport match to the checkout’s origin (e.g., allowing git@github.com:owner/repo.git to match https://github.com/owner/repo.git). This aligns bootstrap repo status/update behavior with real-world git remote URL variations while keeping stricter matching for non-network or unrecognized forms.

Changes:

  • Added transport-agnostic repository identity comparison for common network URL forms (scp-like SSH, ssh://, git://, http(s)://) while preserving exact matching for local paths, file://, Windows paths, and unknown schemes.
  • Introduced focused unit tests covering both positive (same repo across transports) and negative (host/user/port/path conflicts) cases, plus a real-git fixture test via status_one.
  • Updated documentation to describe the new comparison rules and the cases that still conflict.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/system/repos.rs Adds repo_identity parsing/normalization for network remotes and expands tests to validate cross-transport matching and conflict scenarios.
docs/bootstrap/repos.md Documents the transport-agnostic matching behavior and explicitly lists conflict / exact-match cases.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@greptile-apps

greptile-apps Bot commented Jul 16, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a false conflict in [bootstrap.repos] where an existing checkout whose origin uses a different transport was rejected against a config URL pointing to the same repository. The fix introduces repo_identity, which reduces the three recognized network URL forms — scp-style, ssh://, and https:// — to a normalized identity string, and falls back to that comparison only when exact/normalized matching has already failed.

  • src/system/repos.rs: New repo_identity and repo_identity_parts helpers implement the transport-agnostic comparison, dropping the conventional git user and .git suffix and normalizing host case. A comprehensive test suite covers positive cross-transport matches, all documented negative cases (different host, ssh alias, port mismatch, non-git user, userless ssh, insecure transports, query strings, local paths), and a real-git integration test via status_one.
  • docs/bootstrap/repos.md: "Safe updates only" bullet updated to enumerate the three recognized forms and the full list of exact-match-only cases, accurately reflecting the implementation.

Confidence Score: 5/5

Safe to merge — the change is narrowly scoped to URL comparison logic with no effect on clone/fetch/pull mechanics, and every edge case in the agreed spec has a corresponding test.

The new repo_identity path only runs when both exact and normalized matching have already failed, so existing behaviour is fully preserved. The identity reduction is deterministic: .git suffix and the git user are stripped before comparison, host case is normalized, and explicit ports remain in the identity string. All three accepted forms and every documented exact-match-only case have a unit test; status_recognizes_origin_across_transports exercises the full status_one path with a real git fixture. No data is mutated by this change.

No files require special attention.

Important Files Changed

Filename Overview
src/system/repos.rs Adds repo_identity and repo_identity_parts to compare SSH/HTTPS URLs transport-agnostically; origin_matches_config falls back to identity comparison after exact/normalized matching; full unit and integration test coverage added.
docs/bootstrap/repos.md Expands the Safe updates only bullet to document the three recognized transport-agnostic forms and the full set of exact-match-only cases, matching the implementation precisely.

Reviews (3): Last reviewed commit: "Keep https userinfo out of the identity ..." | Re-trigger Greptile

Comment thread docs/bootstrap/repos.md Resolved

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/system/repos.rs`:
- Around line 451-453: Update repo_identity() to account for URL query
parameters when constructing the repository identity: either return None
whenever url.query() is present or pass the query through repo_identity_parts so
distinct remotes remain distinct. Preserve the existing handling for URLs
without queries.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 8a3bd964-cb2f-4689-b759-e2fdeb859e14

📥 Commits

Reviewing files that changed from the base of the PR and between 7214774 and 54767a6.

📒 Files selected for processing (2)
  • docs/bootstrap/repos.md
  • src/system/repos.rs

Comment thread src/system/repos.rs Resolved

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 54767a6dd6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/system/repos.rs Resolved
…ies and userless ssh

Review round: tighten repo_identity to exactly the jdx#10997 contract.

- Only scp-like git@host:path, ssh:// with an explicit user, and https://
  participate in cross-transport identity. http:// and git:// keep exact
  matching — updates pull through the checkout's existing origin, so
  equating them with a configured https url would silently preserve an
  insecure transport.
- ssh forms without a user keep exact matching: git resolves an omitted
  ssh user to the current login user, not git, so a userless origin can be
  a different remote view than git@.
- URLs carrying a query or fragment keep exact matching — url.path()
  comparison would collapse distinct ?tenant= remotes.

Negative tests added for each; docs restated as an exact three-form list.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6bb1bffd92

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/system/repos.rs Resolved
https userinfo is credential material, not repository identity: an origin
ssh://alice@example.com/team/repo must not match a configured
https://alice@example.com/team/repo just because the strings share a user.
userinfo-bearing https URLs now stay on the exact-match path. Negative
tests added.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cdcb6c4e38

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/system/repos.rs Resolved
@jdx
jdx merged commit 95ca0a7 into jdx:main Jul 16, 2026
34 checks passed
@jeremy
jeremy deleted the bootstrap-repos-origin-transport branch July 16, 2026 15:12
jeremy added a commit to basecamp/fizzy that referenced this pull request Jul 27, 2026
Bumps this repo's vendored floor pair — min_version in .mise.toml and
mise_min_version in bin/setup — in lockstep with the fleet-wide raise to
a mise containing jdx/mise#11034 (transport-agnostic repo-origin
comparison), which the docker-dev-origin v2 setup block relies on.

Why 2026.7.10: upstream tagged but never published v2026.7.8–v2026.7.10
(release-pipeline failure; v2026.7.11 is the first published release
since 7.7). GitHub releases and brew now carry 2026.7.14, but Arch's
extra/mise — the Omarchy suite's only channel — was built from the
unpublished v2026.7.10 tag, so 2026.7.10 is the highest floor every
channel satisfies today (ancestry: compare v2026.7.10...95ca0a7b =
behind). Setup upgrades mise in place, so un-upgraded machines converge
on their next bin/setup run; until then a raised .mise.toml floor errors
on every mise invocation in this checkout (announce before landing).
jeremy added a commit to basecamp/fizzy that referenced this pull request Jul 27, 2026
Bumps this repo's vendored floor pair — min_version in .mise.toml and
mise_min_version in bin/setup — in lockstep with the fleet-wide raise to
a mise containing jdx/mise#11034 (transport-agnostic repo-origin
comparison), which the docker-dev-origin v2 setup block relies on.

Why 2026.7.10: upstream tagged but never published v2026.7.8–v2026.7.10
(release-pipeline failure; v2026.7.11 is the first published release
since 7.7). GitHub releases and brew now carry 2026.7.14, but Arch's
extra/mise — the Omarchy suite's only channel — was built from the
unpublished v2026.7.10 tag, so 2026.7.10 is the highest floor every
channel satisfies today (ancestry: compare v2026.7.10...95ca0a7b =
behind). Setup upgrades mise in place, so un-upgraded machines converge
on their next bin/setup run; until then a raised .mise.toml floor errors
on every mise invocation in this checkout (announce before landing).
jeremy added a commit to basecamp/fizzy that referenced this pull request Jul 27, 2026
…https origins (#2998)

Byte-identical swap to shipyard's canonical v2 block (verified with the
audit parser, not by eye). mise ≥ the raised fleet floor compares repo
origins transport-agnostically (jdx/mise#11034), so v1's ssh-rewrite arm
is gone — canonical ssh origins keep updating through ssh untouched. In
its place, the narrow gap #144 deferred: an existing clean checkout whose
origin already names the canonical repo over https gets a noninteractive
auth probe of its actual origin before mise pulls through it, stopping
with guidance that names the failing origin and both remedies. Dirty,
foreign, and malformed checkouts still fall through to mise's own
diagnostics.

Requires the fleet floor raise to land first (this block only runs after
bin/setup's floor check passes).
rhysb27 pushed a commit to rhysb27/fizzy that referenced this pull request Sep 16, 2026
Bumps this repo's vendored floor pair — min_version in .mise.toml and
mise_min_version in bin/setup — in lockstep with the fleet-wide raise to
a mise containing jdx/mise#11034 (transport-agnostic repo-origin
comparison), which the docker-dev-origin v2 setup block relies on.

Why 2026.7.10: upstream tagged but never published v2026.7.8–v2026.7.10
(release-pipeline failure; v2026.7.11 is the first published release
since 7.7). GitHub releases and brew now carry 2026.7.14, but Arch's
extra/mise — the Omarchy suite's only channel — was built from the
unpublished v2026.7.10 tag, so 2026.7.10 is the highest floor every
channel satisfies today (ancestry: compare v2026.7.10...95ca0a7b =
behind). Setup upgrades mise in place, so un-upgraded machines converge
on their next bin/setup run; until then a raised .mise.toml floor errors
on every mise invocation in this checkout (announce before landing).
rhysb27 pushed a commit to rhysb27/fizzy that referenced this pull request Sep 16, 2026
…https origins (basecamp#2998)

Byte-identical swap to shipyard's canonical v2 block (verified with the
audit parser, not by eye). mise ≥ the raised fleet floor compares repo
origins transport-agnostically (jdx/mise#11034), so v1's ssh-rewrite arm
is gone — canonical ssh origins keep updating through ssh untouched. In
its place, the narrow gap basecamp#144 deferred: an existing clean checkout whose
origin already names the canonical repo over https gets a noninteractive
auth probe of its actual origin before mise pulls through it, stopping
with guidance that names the failing origin and both remedies. Dirty,
foreign, and malformed checkouts still fall through to mise's own
diagnostics.

Requires the fleet floor raise to land first (this block only runs after
bin/setup's floor check passes).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants