From 3ba3521fea621e940923db4c298577c8694f0d7e Mon Sep 17 00:00:00 2001 From: Kai Armstrong Date: Thu, 7 Aug 2025 09:34:19 -0500 Subject: [PATCH] Fix path parameter bug in repository commits API The GET /projects/:id/repository/commits API endpoint with the path parameter incorrectly returned all commits in the project when filtering by a file that had only been modified by one commit, instead of returning just that single commit. The issue was caused by the 'follow' parameter being enabled for single-path requests. This parameter is intended to track file renames but had an unintended side effect where it caused all commits to be returned in certain edge cases. This fix disables the 'follow' parameter when path filtering is active, ensuring that only commits that actually modified the specified file are returned. Expected behavior: - File modified by multiple commits: Returns only those commits - File modified by one commit: Returns only that commit (was broken) - Non-existent file: Returns no commits Closes https://gitlab.com/gitlab-org/gitlab/-/issues/559254 Changelog: fixed --- app/models/repository.rb | 2 +- spec/requests/api/commits_spec.rb | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/app/models/repository.rb b/app/models/repository.rb index 9e2dfebc7cdd3f..61dacd7d454d04 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -152,7 +152,7 @@ def commits(ref = nil, opts = {}) ref: ref, path: opts[:path], author: opts[:author], - follow: Array(opts[:path]).length == 1 && Feature.disabled?(:remove_file_commit_history_following, type: :ops), + follow: opts[:path].blank? && Array(opts[:path]).length == 1 && Feature.disabled?(:remove_file_commit_history_following, type: :ops), limit: opts[:limit], offset: opts[:offset], skip_merges: !!opts[:skip_merges], diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb index 0ac4ad61addd6b..722157e4f6e441 100644 --- a/spec/requests/api/commits_spec.rb +++ b/spec/requests/api/commits_spec.rb @@ -262,6 +262,29 @@ expect(response).to include_limited_pagination_headers expect(response.headers['X-Page']).to eql('1') end + + # Test for GitLab issue #559254 - Path Parameter Bug Fix + it "correctly filters commits for files modified by single commit" do + # Test with a file from the existing test repository that should have limited commits + # The Gemfile.zip in the test repository should have been modified only once or twice + + get api("/projects/#{project_id}/repository/commits", user), params: { path: 'Gemfile.zip' } + + expect(response).to have_gitlab_http_status(:ok) + + # Get all commits for comparison + get api("/projects/#{project_id}/repository/commits", user) + total_commits = json_response.length + + # Re-test the file path filter + get api("/projects/#{project_id}/repository/commits", user), params: { path: 'Gemfile.zip' } + filtered_commits = json_response.length + + # The filtered result should be significantly less than total commits + # If they're equal, the bug is present + expect(filtered_commits).to be < total_commits, + "Path filtering returned #{filtered_commits} commits, same as total #{total_commits}." + end end context 'all optional parameter' do -- GitLab