Draft: feat: add ListContributors RPC for contributor statistics
What does this MR do and why?
Implements a new gRPC endpoint that uses git shortlog to
retrieve contributor statistics. Supports sorting by commits, name, or
email, and can group by either author or committer.
This MR is one of the two paired MRs:
- Rails MR: Draft: feat: add total project contributors panel (gitlab!214624)
- Gitaly MR: Draft: feat: add ListContributors RPC for contr... (!8310)
At a high level, the feature works by creating a new Gitaly RPC ListContributors that wraps git shortlog to stream unique contributor triplets (name, email, commit count). Rails uses this RPC to fetch the project's contributors and displays them in the sidebar. The data is fetched in a background sidekiq job and persisted to a new database table project_contributors to avoid blocking the page load.
Three components power the feature:
- New Gitaly RPC
ListContributors(commit service) that wrapsgit shortlogto stream unique contributor triplets (name, email, commit count) with sorting by commits/name/email and grouping by author or committerlist_contributors.go
- Rails client + repository helper to call the RPC via
Repository#all_contributors, exposed through aProjects::Contributorpersistence layer and a background refresh worker so we never hit the repository on page loadgitlab/app/models/repository.rbgitlab/app/models/projects/contributor.rb-
gitlab/app/workers/projects/contributors_cache_worker.rb).
- A contributors sidebar panel that reads the cached data and augments user popovers with a commit-count row
gitlab/app/views/projects/_contributors_panel.html.hamlgitlab/app/assets/javascripts/user_popovers.js-
gitlab/app/assets/javascripts/vue_shared/components/user_popover/user_popover.vue).
Data Flow Diagram
flowchart LR
subgraph Push ["On Git Push"]
A[git push] --> B[BranchHooksService]
B --> C[ContributorsCacheWorker]
end
subgraph Refresh ["Background Refresh"]
C --> D[Projects::Contributor]
D --> E[Repository]
E --> F[Gitaly RPC]
F --> G[git shortlog]
G --> F
F --> D
D --> H[(project_contributors)]
end
subgraph Render ["On Page View"]
I[User visits project] --> J[contributors_panel.haml]
J --> K[ProjectsHelper]
K --> H
H --> J
J --> L[User Popover]
end
style A fill:#f9f,stroke:#333
style I fill:#bbf,stroke:#333
style H fill:#ffa,stroke:#333
Gitaly side
- RPC definition:
ListContributorsadded toproto/commit.proto, generated stubs, and command metadata marksshortlogas non-ref-mutating (internal/git/gitcmd/command_description.go). - Implementation uses
git shortlog -s -ewith:-
--allwhen no revisions are specified, or specific revisions/branches from the request. - Sorting: default/COMMITS uses
-n, NAME uses shortlog’s default, EMAIL is post-processed with Gosort.Slice. - Contributor grouping:
--group=author(default) or--group=committerper request enum. - Output parsed via regex and streamed using
chunk.Newto avoid huge single messages.
-
- Validation: repository is validated, each revision checked via
git.ValidateRevision(allows pseudo refs but blocks--/NUL), errors wrapped withstructerr. - Tests (
internal/gitaly/service/commit/list_contributors_test.go) cover sorting modes, revision filtering, empty repo behavior, and invalid input.
Edited by Michael Angelo Rivera