Skip to content

fix(api): return a single object for an exact git ref - #38735

Open
davidpavlovschi wants to merge 1 commit into
go-gitea:mainfrom
davidpavlovschi:fix/git-ref-exact-match
Open

fix(api): return a single object for an exact git ref#38735
davidpavlovschi wants to merge 1 commit into
go-gitea:mainfrom
davidpavlovschi:fix/git-ref-exact-match

Conversation

@davidpavlovschi

Copy link
Copy Markdown

GET /repos/{owner}/{repo}/git/refs/{ref} returned an array even when the ref matched exactly, contradicting the documented behavior. The route passes the filter without the refs/ prefix (heads/main) while the reference name is fully qualified (refs/heads/main), so the exact-match branch in getGitRefsInternal was dead code.

The check now also accepts "refs/"+filter; prefix filters such as heads keep returning a list. TestAPIReposGitRefs covers both cases.

Fixes #38190

AI was used to assist with this change.

The ref filter from the route has no "refs/" prefix, so the exact-match
branch in getGitRefsInternal never fired and GET /repos/{owner}/{repo}/git/refs/{ref}
always returned an array.

Fixes go-gitea#38190

Signed-off-by: davidpavlovschi <davidpavlov2048@gmail.com>
@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Aug 1, 2026
@github-actions github-actions Bot added topic/api Concerns mainly the API type/bug labels Aug 1, 2026
if len(apiRefs) == 1 && apiRefs[0].Ref == filter {
// If single reference is found and it matches filter exactly return it as object.
// The filter may omit the "refs/" prefix, while the reference name always has it.
if len(apiRefs) == 1 && (apiRefs[0].Ref == filter || apiRefs[0].Ref == "refs/"+filter) {

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.

why apiRefs[0].Ref == filter still makes sense?

AddTokenAuth(token)
resp := MakeRequest(t, req, http.StatusOK)
var ref api.Reference
DecodeJSON(t, resp, &ref)

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.

Take a look at the comment of DecodeJSON

if len(apiRefs) == 1 && apiRefs[0].Ref == filter {
// If single reference is found and it matches filter exactly return it as object.
// The filter may omit the "refs/" prefix, while the reference name always has it.
if len(apiRefs) == 1 && (apiRefs[0].Ref == filter || apiRefs[0].Ref == "refs/"+filter) {

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.

Another question: what is "exact match"?

For example: for branch "main" and "main1", when you query "main", then len(apiRefs) == 1 or 2? What's the response?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. topic/api Concerns mainly the API type/bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

API incompatibility: GetGitRefs returns array for heads/{branch} even when there is a single match

3 participants