Repository navigation
Keep the connector's GitHub commands on https whatever the machine's Git rewrites - #772
Merged
Merged
Conversation
…Git rewrites A machine whose Git configuration sends https://github.com/ to SSH (a url.<base>.insteadOf rule, which is very common) ran the connector's clones over SSH. The service has no SSH agent, so the token Chopin issued was never used, and the work failed with only "Could not read from remote repository", though the person's own shell worked. The connector's Git commands for a repository now carry, through the environment, rules that keep that repository's address on https for fetches and pushes, and map its SSH forms to https. Git rewrites the longest matching prefix and, between equally long ones, the first, which is the person's; the repository's own address is longer than any rule for the host or the owner, so it wins. Nothing is written to the global configuration or a checkout's own, and the rest of the person's configuration applies as it is. This covers the clone and fetch of a repository without a checkout, the agent's environment, the fetch of a run's commit into a registered checkout, and the Planner command. When a failure still looks like SSH, the error now says which rewrite did it and what to do, instead of only Git's fatal line. The local-GitHub test fixture simulated GitHub with a global insteadOf, which this change neutralizes by design. A git wrapper on PATH now maps clone and fetch to local bare repositories after logging the address it would have used. Assistant-model: Claude Opus 5.5 Assistant-workflow: inline Assistant-verification: bun test passed: apps/connector, 272 pass 0 fail Assistant-verification: bun test passed: src/checkouts.test.ts 30 repeats, 0 failures Assistant-verification: types and lint passed: bun run types and bun run ci Assistant-verification: mutation check passed: with the rules removed, five behavior tests fail Co-authored-by: Alex Lavaee <lavaman131@github.com>
lavaman131
force-pushed
the
clone-ignores-url-rewrites
branch
from
November 4, 2026 07:55
d0e8d28 to
b480aa8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The connector's Git commands for GitHub now use the repository's
https://github.com/address and the token Chopin issued, whatever the machine's Git configuration, SSH setup orghlogin says.The problem
A machine whose global Git configuration has
url.git@github.com:.insteadOf = https://github.com/(very common) runs the connector as a background service. The connector clones with the issued token over https, but Git rewrote the address to SSH, so the token was never used. A service has no SSH agent, and the work failed with onlyfatal: Could not read from remote repository., while the same user's own shell worked.The fix
gitCredentials(file, repository)andgithubEnvironment(github, repository)now also pass, through the environment (GIT_CONFIG_COUNT/KEY/VALUE), for that repository only:url.https://github.com/<owner>/<name>.insteadOfand.pushInsteadOf, each mapping the address to itself;git@github.com:<owner>/<name>andssh://git@github.com/<owner>/<name>, so a checkout whose origin is an SSH address reaches GitHub over https too.Both spellings of the owner and name (as Chopin gives them and lowercase) are covered. Nothing is written to the global configuration or to a checkout's own, so the Planner's refusal of a checkout with its own rewrite or credential settings is untouched, and the rest of the person's configuration (identity, signing, other rules) applies as it is.
The Git precedence this relies on, checked with Git 2.43 in the tests
A
url.<base>.insteadOfrule rewrites the longest matching prefix. Between two equally long rules the first wins, which is the person's, because command-line and environment configuration come last. So a same-length rule forhttps://github.com/does not override them, but a rule for the repository's own address is longer than any rule for the host or the owner.pushInsteadOfis its own list and applies to pushes, so it is set too.Limits: a person's rule written for exactly this repository's address ties with the new rule and still wins, and other repositories are left as the person has them, since the rules name only the repository the token is for.
Where it applies
checkouts.ts: the clone and every later fetch of a repository without a registered checkout.run.ts: the agent's environment (its fetches and pushes), and the fetch of the run's commit into a registered checkout, which used to take the machine's own credentials and so could not reach GitHub from a service. A spike with a registered checkout keeps its old behavior, since a spike never pushes.planner.ts: the Planner command's environment, so its own Git and its agent's keep to https.When it still goes to SSH
A failure that looks like SSH (
Could not read from remote repository,Permission denied (publickey),Host key verification failed) now asks Git how this process's own configuration treats the repository's address, and says so:Tokens stay masked as before.
Tests
With a real Git binary:
.git, other repositories untouched, SSH origins mapped, and pushes;user.namestill applies, and the clone's own configuration holds none of it;run.test.ts) and the Planner command's (planner.test.ts) under a rewrite to SSH;The local-GitHub fixture in
checkouts.test.tssimulated GitHub with a globalinsteadOf, which this change correctly neutralizes. Agitwrapper on PATH now maps clone and fetch to local bare repositories after logging the address it would have used.Removing the rules makes the five behavior tests fail. The connector suite passes (272 pass, 0 fail), the new
checkouts.test.tsran 30 times without a failure, andbun run typesandbun run cipass.Assistant-model: Claude Opus 5.5
Assistant-workflow: inline
Assistant-verification: bun test passed: apps/connector, 272 pass 0 fail
Assistant-verification: bun test passed: src/checkouts.test.ts 30 repeats, 0 failures
Assistant-verification: types and lint passed: bun run types and bun run ci
Assistant-verification: mutation check passed: with the rules removed, five behavior tests fail