Commit 219836b9 authored by Nick Thomas's avatar Nick Thomas

Merge branch 'api-compare-across-projects' into 'master'

'/projects/:id/repository/compare' supports comparing branches/commits on different projects.

See merge request gitlab-org/gitlab!57418
parents c7af1d64 254f1ae5
---
title: "'/projects/:id/repository/compare' supports comparing branches/commits on
different projects."
merge_request: 57418
author: Exchizz (@Exchizz)
type: added
...@@ -157,12 +157,13 @@ GET /projects/:id/repository/compare ...@@ -157,12 +157,13 @@ GET /projects/:id/repository/compare
Supported attributes: Supported attributes:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| :--------- | :------------- | :------- | :---------- | | :--------- | :------------- | :------- | :---------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user. | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user. |
| `from` | string | yes | The commit SHA or branch name. | | `from` | string | yes | The commit SHA or branch name. |
| `to` | string | yes | The commit SHA or branch name. | | `to` | string | yes | The commit SHA or branch name. |
| `straight` | boolean | no | Comparison method, `true` for direct comparison between `from` and `to` (`from`..`to`), `false` to compare using merge base (`from`...`to`)'. Default is `false`. | | `from_project_id` | integer | no | The ID to compare from |
| `straight` | boolean | no | Comparison method, `true` for direct comparison between `from` and `to` (`from`..`to`), `false` to compare using merge base (`from`...`to`)'. Default is `false`. |
```plaintext ```plaintext
GET /projects/:id/repository/compare?from=master&to=feature GET /projects/:id/repository/compare?from=master&to=feature
......
...@@ -116,10 +116,23 @@ module API ...@@ -116,10 +116,23 @@ module API
params do params do
requires :from, type: String, desc: 'The commit, branch name, or tag name to start comparison' requires :from, type: String, desc: 'The commit, branch name, or tag name to start comparison'
requires :to, type: String, desc: 'The commit, branch name, or tag name to stop comparison' requires :to, type: String, desc: 'The commit, branch name, or tag name to stop comparison'
optional :from_project_id, type: String, desc: 'The project to compare from'
optional :straight, type: Boolean, desc: 'Comparison method, `true` for direct comparison between `from` and `to` (`from`..`to`), `false` to compare using merge base (`from`...`to`)', default: false optional :straight, type: Boolean, desc: 'Comparison method, `true` for direct comparison between `from` and `to` (`from`..`to`), `false` to compare using merge base (`from`...`to`)', default: false
end end
get ':id/repository/compare' do get ':id/repository/compare' do
compare = CompareService.new(user_project, params[:to]).execute(user_project, params[:from], straight: params[:straight]) if params[:from_project_id].present?
target_project = MergeRequestTargetProjectFinder
.new(current_user: current_user, source_project: user_project, project_feature: :repository)
.execute(include_routes: true).find_by_id(params[:from_project_id])
if target_project.blank?
render_api_error!("Target project id:#{params[:from_project_id]} is not a fork of project id:#{params[:id]}", 400)
end
else
target_project = user_project
end
compare = CompareService.new(user_project, params[:to]).execute(target_project, params[:from], straight: params[:straight])
if compare if compare
present compare, with: Entities::Compare present compare, with: Entities::Compare
......
...@@ -6,6 +6,7 @@ require 'mime/types' ...@@ -6,6 +6,7 @@ require 'mime/types'
RSpec.describe API::Repositories do RSpec.describe API::Repositories do
include RepoHelpers include RepoHelpers
include WorkhorseHelpers include WorkhorseHelpers
include ProjectForksHelper
let(:user) { create(:user) } let(:user) { create(:user) }
let(:guest) { create(:user).tap { |u| create(:project_member, :guest, user: u, project: project) } } let(:guest) { create(:user).tap { |u| create(:project_member, :guest, user: u, project: project) } }
...@@ -392,6 +393,28 @@ RSpec.describe API::Repositories do ...@@ -392,6 +393,28 @@ RSpec.describe API::Repositories do
expect(json_response['diffs']).to be_present expect(json_response['diffs']).to be_present
end end
it "compare commits between different projects with non-forked relation" do
public_project = create(:project, :repository, :public)
get api(route, current_user), params: { from: sample_commit.parent_id, to: sample_commit.id, from_project_id: public_project.id }
expect(response).to have_gitlab_http_status(:bad_request)
end
it "compare commits between different projects" do
group = create(:group)
group.add_owner(current_user)
forked_project = fork_project(project, current_user, repository: true, namespace: group)
forked_project.repository.create_ref('refs/heads/improve/awesome', 'refs/heads/improve/more-awesome')
get api(route, current_user), params: { from: 'improve/awesome', to: 'feature', from_project_id: forked_project.id }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['commits']).to be_present
expect(json_response['diffs']).to be_present
end
it "compares same refs" do it "compares same refs" do
get api(route, current_user), params: { from: 'master', to: 'master' } get api(route, current_user), params: { from: 'master', to: 'master' }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment