[go: up one dir, main page]

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:

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 wraps git shortlog to stream unique contributor triplets (name, email, commit count) with sorting by commits/name/email and grouping by author or committer
    • list_contributors.go
  • Rails client + repository helper to call the RPC via Repository#all_contributors, exposed through a Projects::Contributor persistence layer and a background refresh worker so we never hit the repository on page load
    • gitlab/app/models/repository.rb
    • gitlab/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.haml
    • gitlab/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: ListContributors added to proto/commit.proto, generated stubs, and command metadata marks shortlog as non-ref-mutating (internal/git/gitcmd/command_description.go).
  • Implementation uses git shortlog -s -e with:
    • --all when 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 Go sort.Slice.
    • Contributor grouping: --group=author (default) or --group=committer per request enum.
    • Output parsed via regex and streamed using chunk.New to avoid huge single messages.
  • Validation: repository is validated, each revision checked via git.ValidateRevision (allows pseudo refs but blocks --/NUL), errors wrapped with structerr.
  • 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

Merge request reports

Loading