Add stats field + first_parent/order arguments to repository.commits for list_commits MCP tool

Note

This is not an MCP tool issue itself — it's a GraphQL API prerequisite for #605875 (list_commits MCP tool), found while redirecting that issue's implementation plan from a REST wrap to the existing repository.commits query.

Problem Statement / Use Case

Query.project { repository { commits } } (Resolvers::Repositories::CommitsResolver) covers ref/path/author/committedBefore/committedAfter with cursor pagination, but is missing three things #605875 (list_commits MCP tool) needs to fully replace the REST-backed tool:

  1. with_stats — per-commit line counts (additions/deletions/total). CommitType exposes only diffs (full patches), which is the opposite of what a commit list wants: cheap counts without pulling patches. The REST commits endpoint has with_stats (Entities::CommitWithStats).
  2. first_parent — follow only the first parent of merge commits.
  3. order — topological vs. date ordering.

The model layer already supports the last two: Gitlab::Git::Repository#list_commits (and app/models/repository.rb#list_commits) accept first_parent: and order: — they're just not exposed as resolver arguments. Stats are available via Commit#diff_stats (Gitaly), surfaced in REST but not on CommitType.

Proposed Change

  • Add a stats field to Types::Repositories::CommitType returning additions/deletions/total (from Commit#diff_stats), lookahead-gated so it only calls Gitaly when selected.
  • Add first_parent and order arguments to Resolvers::Repositories::CommitsResolver, passed through to repository.list_commits (which already accepts them).
  • (all from the REST tool is lower priority and has different semantics — treat separately / out of scope here unless a concrete need appears.)

Resources

  • app/graphql/resolvers/repositories/commits_resolver.rb — add first_parent/order arguments; list_commits_arguments already forwards **arguments to repository.list_commits.
  • app/models/repository.rb:199 #list_commits and lib/gitlab/git/repository.rb:1173 #list_commits — already take first_parent:/order:.
  • app/graphql/types/repositories/commit_type.rb — add the stats field (no stats field exists today, only diffs).
  • app/models/commit.rb:368 #diff_stats (Gitaly diff_stats) — the data source for the stats field; lib/api/entities/commit_stats.rb is the REST shape to mirror (additions/deletions/total).

Implementation Plan

  1. Add argument :first_parent, GraphQL::Types::Boolean, required: false and argument :order, GraphQL::Types::String, required: false (or a small enum) to CommitsResolver, forwarded through list_commits_arguments.
  2. Add a stats field to CommitType (additions/deletions/total via Commit#diff_stats), gated on lookahead/selection so a commit list doesn't call Gitaly per node unless stats is requested.
  3. Specs: resolver spec for first_parent/order filtering; type spec for stats; spec/graphql/all_queries_spec.rb coverage once #605875 commits its .graphql file using the new field/args.
Edited by 🤖 GitLab Bot 🤖