Skip to content

fix(remote): resolve a git ref to the exact branch or tag - #14268

Open
breken-ai wants to merge 1 commit into
docker:mainfrom
breken-ai:fix-git-remote-ref-match
Open

breken-ai wants to merge 1 commit into
docker:mainfrom
breken-ai:fix-git-remote-ref-match

Conversation

@breken-ai

Copy link
Copy Markdown

What I did

A git remote compose file could be loaded from the wrong branch or tag. resolveGitRef (pkg/remote/git.go) runs git ls-remote --exit-code <remote> <ref> and takes the sha from the first 40 bytes of the output. But ls-remote matches its pattern against the tail of every ref name, and prints the matches in ref order:

$ git ls-remote git://127.0.0.1:19418/repo.git main
2ab76064dfa2e777396d568fcf2657a403457c16	refs/heads/feature/main
99220f3d46cd220fcf26138bf963899463bd12a9	refs/heads/main

So ...#main resolves to feature/main whenever such a branch exists. In the same way, #v1 resolves to a release/v1 branch instead of the v1 tag.

The fix reads every line of the ls-remote output and picks the ref whose name matches exactly. It checks names in git's own lookup order: the ref as given, then refs/<ref>, refs/tags/<ref> and refs/heads/<ref>.

End to end, with a local git daemon serving a repo whose compose.yaml uses image: from-main on main and image: from-feature-main on feature/main:

$ docker compose -f 'git://127.0.0.1:19418/repo.git#main' config --images
from-feature-main   # main @ 32bddfc4
from-main           # this branch

Tests:

  • New TestResolveGitRefPicksExactRef builds a real local repo with main, feature/main, a v1 tag and a release/v1 branch, then resolves main, refs/heads/main and v1. On main, main and v1 resolve to the wrong sha. They pass here.
  • New TestMatchLsRemoteRef covers the lookup order (a tag wins over a branch with the same name, as in git) and the error for a ref with no match.
  • go test ./pkg/remote/ passes. golangci-lint run --build-tags e2e ./pkg/remote/... (v2.13.2): 0 issues.

This PR includes AI_AGENT_DISCLOSURE.md as AGENTS.md asks. The ai-disclosure gate blocks merge until a human reviews the change and removes the file.

Related issue

No existing issue or PR found.

(not mandatory) A picture of a cute animal, if possible in relation to what you did

🐿️ (fetched the right branch this time)

🤖 Generated with Claude Code

`git ls-remote <remote> <ref>` matches the pattern against the tail of
every ref name, so `#main` also lists `refs/heads/feature/main`, and
`#v1` also lists `refs/heads/release/v1`. Those sort first, and
resolveGitRef took the sha of the first line, so compose loaded the
compose file from the wrong branch.

Pick the ls-remote line whose ref name matches exactly, in git's own
lookup order (as given, refs/, refs/tags/, refs/heads/).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: breken-ai <312387581+breken-ai@users.noreply.github.com>
@breken-ai
breken-ai requested review from a team as code owners September 25, 2026 23:36
@breken-ai
breken-ai requested review from glours and ndeloof September 25, 2026 23:36

This branch has not been deployed

No deployments
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.

1 participant