Commit 71d71afb authored by Bob Van Landuyt's avatar Bob Van Landuyt

Allow getting the merge base of multiple revisions

As we now support getting the merge base for multiple revisions in
gitaly, we can provide this functionality in our API
parent 75723034
...@@ -881,10 +881,12 @@ class Repository ...@@ -881,10 +881,12 @@ class Repository
delegate :merged_branch_names, to: :raw_repository delegate :merged_branch_names, to: :raw_repository
def merge_base(first_commit_id, second_commit_id) def merge_base(*commits_or_ids)
first_commit_id = commit(first_commit_id).try(:id) || first_commit_id commit_ids = commits_or_ids.map do |commit_or_id|
second_commit_id = commit(second_commit_id).try(:id) || second_commit_id commit_or_id.is_a?(::Commit) ? commit_or_id.id : commit_or_id
raw_repository.merge_base(first_commit_id, second_commit_id) end
raw_repository.merge_base(*commit_ids)
end end
def ancestor?(ancestor_id, descendant_id) def ancestor?(ancestor_id, descendant_id)
......
---
title: Allow finding the common ancestor for multiple revisions through the API
merge_request: 22295
author:
type: changed
...@@ -216,7 +216,7 @@ GET /projects/:id/repository/merge_base ...@@ -216,7 +216,7 @@ GET /projects/:id/repository/merge_base
| 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) | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
| `refs` | array | yes | The refs to find the common ancestor of, for now only 2 refs are supported | | `refs` | array | yes | The refs to find the common ancestor of, multiple refs can be passed |
```bash ```bash
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/5/repository/merge_base?refs[]=304d257dcb821665ab5110318fc58a007bd104ed&refs[]=0031876facac3f2b2702a0e53a26e89939a42209" curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/5/repository/merge_base?refs[]=304d257dcb821665ab5110318fc58a007bd104ed&refs[]=0031876facac3f2b2702a0e53a26e89939a42209"
......
...@@ -130,18 +130,13 @@ module API ...@@ -130,18 +130,13 @@ module API
success Entities::Commit success Entities::Commit
end end
params do params do
# For now we just support 2 refs passed, but `merge-base` supports
# multiple defining this as an Array instead of 2 separate params will
# make sure we don't need to deprecate this API in favor of one
# supporting multiple commits when this functionality gets added to
# Gitaly
requires :refs, type: Array[String] requires :refs, type: Array[String]
end end
get ':id/repository/merge_base' do get ':id/repository/merge_base' do
refs = params[:refs] refs = params[:refs]
unless refs.size == 2 if refs.size < 2
render_api_error!('Provide exactly 2 refs', 400) render_api_error!('Provide at least 2 refs', 400)
end end
merge_base = Gitlab::Git::MergeBase.new(user_project.repository, refs) merge_base = Gitlab::Git::MergeBase.new(user_project.repository, refs)
......
...@@ -382,9 +382,9 @@ module Gitlab ...@@ -382,9 +382,9 @@ module Gitlab
end end
# Returns the SHA of the most recent common ancestor of +from+ and +to+ # Returns the SHA of the most recent common ancestor of +from+ and +to+
def merge_base(from, to) def merge_base(*commits)
wrapped_gitaly_errors do wrapped_gitaly_errors do
gitaly_repository_client.find_merge_base(from, to) gitaly_repository_client.find_merge_base(*commits)
end end
end end
......
...@@ -2386,4 +2386,15 @@ describe Repository do ...@@ -2386,4 +2386,15 @@ describe Repository do
end end
end end
end end
describe '#merge_base' do
set(:project) { create(:project, :repository) }
subject(:repository) { project.repository }
it 'only makes one gitaly call' do
expect(Gitlab::GitalyClient).to receive(:call).once.and_call_original
repository.merge_base('master', 'fix')
end
end
end end
...@@ -468,7 +468,7 @@ describe API::Repositories do ...@@ -468,7 +468,7 @@ describe API::Repositories do
describe 'GET :id/repository/merge_base' do describe 'GET :id/repository/merge_base' do
let(:refs) do let(:refs) do
%w(304d257dcb821665ab5110318fc58a007bd104ed 0031876facac3f2b2702a0e53a26e89939a42209) %w(304d257dcb821665ab5110318fc58a007bd104ed 0031876facac3f2b2702a0e53a26e89939a42209 570e7b2abdd848b95f2f578043fc23bd6f6fd24d)
end end
subject(:request) do subject(:request) do
...@@ -534,7 +534,7 @@ describe API::Repositories do ...@@ -534,7 +534,7 @@ describe API::Repositories do
request request
expect(response).to have_gitlab_http_status(:bad_request) expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message']).to eq('Provide exactly 2 refs') expect(json_response['message']).to eq('Provide at least 2 refs')
end end
end end
end end
......
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