summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Van Landuyt <bob@vanlanduyt.co>2018-10-11 16:27:04 +0200
committerBob Van Landuyt <bob@vanlanduyt.co>2018-10-12 11:41:22 +0200
commit71d71afb3ac5f302470e66ace4f59e247249d99e (patch)
tree0d869436e2ab72454ebb117cc3808ad764652e55
parent75723034cee27d387d7ac7edb88d1520bb3a6b7b (diff)
downloadgitlab-ce-71d71afb3ac5f302470e66ace4f59e247249d99e.tar.gz
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
-rw-r--r--app/models/repository.rb10
-rw-r--r--changelogs/unreleased/bvl-merge-base-multiple-revisions.yml5
-rw-r--r--doc/api/repositories.md2
-rw-r--r--lib/api/repositories.rb9
-rw-r--r--lib/gitlab/git/repository.rb4
-rw-r--r--spec/models/repository_spec.rb11
-rw-r--r--spec/requests/api/repositories_spec.rb4
7 files changed, 29 insertions, 16 deletions
diff --git a/app/models/repository.rb b/app/models/repository.rb
index a3a3ce179fc..2c28ea64066 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -881,10 +881,12 @@ class Repository
delegate :merged_branch_names, to: :raw_repository
- def merge_base(first_commit_id, second_commit_id)
- first_commit_id = commit(first_commit_id).try(:id) || first_commit_id
- second_commit_id = commit(second_commit_id).try(:id) || second_commit_id
- raw_repository.merge_base(first_commit_id, second_commit_id)
+ def merge_base(*commits_or_ids)
+ commit_ids = commits_or_ids.map do |commit_or_id|
+ commit_or_id.is_a?(::Commit) ? commit_or_id.id : commit_or_id
+ end
+
+ raw_repository.merge_base(*commit_ids)
end
def ancestor?(ancestor_id, descendant_id)
diff --git a/changelogs/unreleased/bvl-merge-base-multiple-revisions.yml b/changelogs/unreleased/bvl-merge-base-multiple-revisions.yml
new file mode 100644
index 00000000000..4075e35fce9
--- /dev/null
+++ b/changelogs/unreleased/bvl-merge-base-multiple-revisions.yml
@@ -0,0 +1,5 @@
+---
+title: Allow finding the common ancestor for multiple revisions through the API
+merge_request: 22295
+author:
+type: changed
diff --git a/doc/api/repositories.md b/doc/api/repositories.md
index a4fdeca162e..f5ac3816fe5 100644
--- a/doc/api/repositories.md
+++ b/doc/api/repositories.md
@@ -216,7 +216,7 @@ GET /projects/:id/repository/merge_base
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `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
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/5/repository/merge_base?refs[]=304d257dcb821665ab5110318fc58a007bd104ed&refs[]=0031876facac3f2b2702a0e53a26e89939a42209"
diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb
index 5125f302fbb..dc844c0bd27 100644
--- a/lib/api/repositories.rb
+++ b/lib/api/repositories.rb
@@ -130,18 +130,13 @@ module API
success Entities::Commit
end
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]
end
get ':id/repository/merge_base' do
refs = params[:refs]
- unless refs.size == 2
- render_api_error!('Provide exactly 2 refs', 400)
+ if refs.size < 2
+ render_api_error!('Provide at least 2 refs', 400)
end
merge_base = Gitlab::Git::MergeBase.new(user_project.repository, refs)
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index 4218e812146..9df04372cc2 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -382,9 +382,9 @@ module Gitlab
end
# 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
- gitaly_repository_client.find_merge_base(from, to)
+ gitaly_repository_client.find_merge_base(*commits)
end
end
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index aed8e02cc23..6f5a4118b95 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -2386,4 +2386,15 @@ describe Repository do
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
diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb
index 519638ebb82..fa38751fe58 100644
--- a/spec/requests/api/repositories_spec.rb
+++ b/spec/requests/api/repositories_spec.rb
@@ -468,7 +468,7 @@ describe API::Repositories do
describe 'GET :id/repository/merge_base' do
let(:refs) do
- %w(304d257dcb821665ab5110318fc58a007bd104ed 0031876facac3f2b2702a0e53a26e89939a42209)
+ %w(304d257dcb821665ab5110318fc58a007bd104ed 0031876facac3f2b2702a0e53a26e89939a42209 570e7b2abdd848b95f2f578043fc23bd6f6fd24d)
end
subject(:request) do
@@ -534,7 +534,7 @@ describe API::Repositories do
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