Avoid loading CommitsMetadata in MergeRequest#changed_paths

What does this MR do and why?

MergeRequest#changed_paths passed the full CommitCollection (from MergeRequest#commits) to find_changed_paths. Building that collection triggers MergeRequestDiff#load_commitsdiff_commits.with_users which loads every CommitsMetadata AR object (including message, authored_date, committed_date, sha, plus two DiffCommitUser joins) for the entire diff. All of that was just to produce SHAs, since find_changed_paths_request only reads object.sha.

Changes:

  1. commit_service.rb- add when String to find_changed_paths_request

SHA strings (exactly 40 or 64 hex chars, validated via Gitlab::Git.commit_id?) are now turned into CommitRequest objects directly. Non-hex strings still fail commit_id? and are filtered out, so the existing "invalid objects" test is unaffected.

  1. merge_request.rb - use commit_shas instead of commits when FF optimised_commits_for_mr_changed_paths is enabled.

commit_shas delegates to merge_request_diff.commit_shas which, when the association isn't loaded, runs commit_shas_from_metadata, a single SQL query that returns only hex SHA strings. Which avoids loading CommitsMetadata and DiffCommitUser objects.

Tests updated:

  • merge_request_spec.rb: #changed_paths now stubs commit_shas instead of commits

  • commit_service_spec.rb: new context showing SHA strings passed directly produce identical Gitaly requests to Commit objects

References

related to #592062

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Eugenia Grieff

Merge request reports

Loading