Return structured error for dangling refs in RefExists

What does this MR do and why?

When a reference exists but the object it points to is missing, RefExists returned a generic INTERNAL: exit status 128 error. This surfaced in GitLab Rails as an opaque GRPC::Internal from ref_exists?, breaking repository mirroring and giving operators no actionable signal about the dangling reference.

This MR detects that condition and returns a typed FAILED_PRECONDITION error carrying a RefExistsError detail with the reference name and object ID:

  • Detect the exit code 128 from git show-ref --verify that indicates the reference exists but its target object is missing.
  • Confirm the dangling state by resolving the reference and reading the object via ReadObjectInfo.
  • Return a typed FAILED_PRECONDITION error so callers can identify and handle the dangling reference.

Verified end-to-end via Rails console against a project with a fabricated dangling keep-around ref: ref_exists? now raises 9:reference "refs/keep-around/<oid>" points to missing object <oid> (gRPC FAILED_PRECONDITION) instead of the previous 13:exit status 128 (gRPC INTERNAL).

References

Contributes to https://gitlab.com/gitlab-com/request-for-help/-/work_items/4994

A follow-up GitLab Rails change is required to consume the new error (bump the gitaly gem and add a handle_detailed_error branch for Gitaly::ReferenceUnresolvableError) to fully unblock mirroring.

How to set up and validate locally

  1. Build Gitaly with this branch.
  2. Create a dangling keep-around ref in a test repo: write a commit, point refs/keep-around/<oid> at it, then delete the loose object.
  3. In the Rails console: Project.find(<id>).repository.ref_exists?(\"refs/keep-around/<oid>\").
  4. Observe it raises 9:reference \"...\" points to missing object ... (FAILED_PRECONDITION) rather than 13:exit status 128.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Merge request reports

Loading
Loading