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_commits → diff_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:
-
commit_service.rb- add whenStringtofind_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.
-
merge_request.rb- usecommit_shasinstead ofcommitswhen FFoptimised_commits_for_mr_changed_pathsis 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_pathsnow stubscommit_shasinstead ofcommits -
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.