Skip to content

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

Description

@rogerlga

Description

Gitea’s GET /api/v1/repos/{owner}/{repo}/git/refs/{ref} endpoint currently returns a JSON array even when the request targets a single, specific reference such as heads/main. This differs from GitHub’s REST API behavior and breaks clients that expect a single ref object for exact references

Reproduction

  1. Ensure repository has a branch main (so the ref is refs/heads/main).
  2. Call:
    GET /api/v1/repos/{owner}/{repo}/git/refs/heads/main

Actual behavior

Response is an array with a single element:

[
  {
    "ref": "refs/heads/main",
    "url": "...",
    "object": { "type": "commit", "sha": "...", "url": "..." }
  }
]

This leads to deserialization failures in some GitHub API clients expecting an object for an exact ref.

Expected behavior (GitHub-compatible)

For an exact ref request like heads/main, the response should be a single reference object (not an array). Arrays should be reserved for prefix/filtered requests that match multiple refs.

Root cause in current code

In routers/api/v1/repo/git_ref.go, Gitea returns an object only when the filter matches the ref name exactly:

// If single reference is found and it matches filter exactly return it as object
if len(apiRefs) == 1 && apiRefs[0].Ref == filter {
ctx.JSON(http.StatusOK, &apiRefs[0])
return
}

However, for a request like /git/refs/heads/main, filter is heads/main, while the ref name is refs/heads/main. Therefore this condition never matches for the GitHub-style path, and Gitea returns an array even for a single match.

Suggested fix

Normalize the filter before comparison (or relax the comparison) so that heads/main is treated as an exact match for refs/heads/main. For example, when len(apiRefs) == 1, consider returning an object when:

  • apiRefs[0].Ref == filter, or
  • apiRefs[0].Ref == "refs/" + filter

This would preserve the current “prefix search returns list” behavior, but restore GitHub-compatible behavior for exact refs like heads/{branch}.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions