Migrate CountCommits to always use revisions parameter internally

Summary

Migrate the commit_count method to internally convert legacy revision and all parameters to the new revisions parameter when calling Gitaly, while keeping the external API unchanged.

Related to #586893 (closed) and !219416 (merged)

Background

Currently, the commit_count method in Gitlab::GitalyClient::CommitService supports three ways to specify revisions:

  • revision (legacy, passed directly to Gitaly)
  • all: true (legacy, passed directly to Gitaly)
  • revisions (new, passed directly to Gitaly)

This creates multiple code paths in Gitaly. We should normalize all inputs to use the revisions parameter internally before sending to Gitaly.

Proposed Changes

Update Gitlab::GitalyClient::CommitService#commit_count to always convert inputs to revisions:

def commit_count(ref, options = {})
  request = Gitaly::CountCommitsRequest.new(
    repository: @gitaly_repo,
    first_parent: !!options[:first_parent]
  )

  # Convert all inputs to revisions format
  revisions = if options[:revisions].present?
                Array.wrap(options[:revisions])
              elsif options[:all]
                ['--all']
              elsif ref
                [ref]
              else
                raise ArgumentError, "Please specify a revision, all: true, or revisions"
              end

  request.revisions = encode_repeated(revisions)
  
  # ... rest of the method
end

Migration Examples

External API remains unchanged:

# These all continue to work exactly as before
commit_count('master')           # Internally: revisions: ['master']
commit_count(nil, all: true)     # Internally: revisions: ['--all']
commit_count(nil, revisions: ['feature-a', 'feature-b'])  # Internally: revisions: ['feature-a', 'feature-b']

Implementation Plan

  1. Add feature flag: count_commits_use_revisions_only
  2. Update commit_count method:
    • When flag is enabled, convert ref → revisions: [ref]
    • When flag is enabled, convert all: true → revisions: ['--all']
    • Keep existing behavior when flag is disabled
  3. Add comprehensive tests for the conversion logic
  4. Gradual rollout:
    • Enable on GitLab.com staging
    • Monitor for issues
    • Enable on GitLab.com production
    • Enable by default
    • Remove flag and old code paths

Benefits

  • Simplified Gitaly code: Single code path in Gitaly for handling revisions
  • Better maintainability: One way to handle all revision inputs
  • Backward compatible: No changes to external API
  • Future-proof: All code already using the modern parameter internally
  • Easier testing: Single code path to test in Gitaly

Testing Strategy

  • Ensure all existing tests pass with feature flag enabled
  • Add specific tests for the conversion logic:
    • ref → revisions: [ref]
    • all: true → revisions: ['--all']
    • revisions → revisions (passthrough)
  • Test with various combinations of filters (before, after, path, max_count, first_parent)
  • Verify UTF-8 encoding is preserved during conversion
Edited Jan 23, 2026 by 🤖 GitLab Bot 🤖
Assignee Loading
Time tracking Loading