Commits with ambiguous identical short IDs cannot be viewed in UI or via API

Summary

When a commit shares the first 8 characters of another commit in the repository, gitlab-rails is unable to differentiate the ambiguous ref and presents an error in UI and gitaly logs. This is because the ref is truncated in the commit model.

Steps to reproduce

Unsure exactly how to reproduce. The two commits need to have a hash that is identical up to the first 8 characters.

Example Project

Further details can be found in support ticket #546725.

What is the current bug behavior?

When attempting to view the commit, for example at page: https://gitlab.example.com/group/project/-/commit/

UI shows the following when attempting to view the ambiguous commit:

image

Gitaly logs show an error similar to the following:

{
  "args": [
    "/var/opt/gitlab/gitaly/run/gitaly-1292/git-exec-4243301954.d/git",
    "--git-dir",
    "/mnt/gitlab/git-data/repositories/@hashed/7f/22/7f2253d7e228b22a08bda1f09c516f6fead81df6536eb02fa991a34bb38d9be8.git",
    "-c",
    "gc.auto=0",
    "-c",
    "maintenance.auto=0",
    "-c",
    "core.autocrlf=input",
    "-c",
    "core.useReplaceRefs=false",
    "-c",
    "core.fsync=objects,derived-metadata,reference",
    "-c",
    "core.fsyncMethod=fsync",
    "-c",
    "core.packedRefsTimeout=10000",
    "-c",
    "core.filesRefLockTimeout=1000",
    "-c",
    "core.bigFileThreshold=50m",
    "cat-file",
    "--use-mailmap",
    "-Z",
    "--batch-command",
    "--buffer",
    "--end-of-options"
  ],
  "command.cpu_time_ms": 3,
  "command.exitCode": 0,
  "command.inblock": 0,
  "command.maxrss": 595516,
  "command.oublock": 0,
  "command.real_time_ms": 3680,
  "command.system_time_ms": 3,
  "command.user_time_ms": 0,
  "component": "gitaly.UnaryServerInterceptor",
  "correlation_id": "01J20PRR1J467FBZJB34XHGH63",
  "grpc.meta.auth_version": "v2",
  "grpc.meta.client_name": "gitlab-web",
  "grpc.meta.deadline_type": "regular",
  "grpc.meta.method_operation": "accessor",
  "grpc.meta.method_scope": "repository",
  "grpc.meta.method_type": "unary",
  "grpc.method": "FindCommit",
  "grpc.request.deadline": "2024-07-05T05:45:11.821",
  "grpc.request.fullMethod": "/gitaly.CommitService/FindCommit",
  "grpc.request.glProjectPath": "<group>/<project>",
  "grpc.request.glRepository": "project-71",
  "grpc.request.repoPath": "@hashed/7f/22/7f2253d7e228b22a08bda1f09c516f6fead81df6536eb02fa991a34bb38d9be8.git",
  "grpc.request.repoStorage": "default",
  "grpc.service": "gitaly.CommitService",
  "grpc.start_time": "2024-07-05T05:44:41.821",
  "level": "error",
  "msg": "error: short object ID 0c156267 is ambiguous\nhint: The candidates are:\nhint:   0c15626744570 commit 2022-06-13 - Merge branch '[snip]/[snip]' into 'master'\nhint:   0c156267cf060 commit 2024-07-02 - [snip]: [snip]\n",
  "path": "/var/opt/gitlab/gitaly/run/gitaly-1292/git-exec-4243301954.d/git",
  "pid": 1292,
  "remote_ip": "[snip]",
  "span.kind": "server",
  "system": "grpc",
  "time": "2024-07-05T05:44:45.502Z",
  "user_id": "[snip]",
  "username": "[snip]"
}

What is the expected correct behavior?

As a short ID of a commit ref can be ambiguous (admittedly very rare), we could use the full ref when rails constructs the request to gitaly.

Output of checks

Results of GitLab environment info

Observed on GitLab self-managed (helm install) version 16.11.5 - Gitaly running on EC2 instance

Expand for output related to GitLab environment info

(For installations with omnibus-gitlab package run and paste the output of:
`sudo gitlab-rake gitlab:env:info`)

(For installations from source run and paste the output of:
`sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production`)

Results of GitLab application Check

Expand for output related to the GitLab application check

(For installations with omnibus-gitlab package run and paste the output of: sudo gitlab-rake gitlab:check SANITIZE=true)

(For installations from source run and paste the output of: sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production SANITIZE=true)

(we will only investigate if the tests are passing)

Possible fixes

https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/models/commit.rb#L86-89

Assignee Loading
Time tracking Loading