Commit 0a47d192 authored by Zeger-Jan van de Weg's avatar Zeger-Jan van de Weg

Client changes for Tag,BranchNamesContainingCommit

As part of gitlab-org/gitaly#884, this commit contains the client
implementation for both TagNamesContaintingCommit and
BranchNamesContainingCommit. The interface in the Repository model stays
the same, but the implementation on the serverside, e.g. Gitaly, uses
`for-each-ref`, as opposed to `branch` or `tag` which both aren't
plumbing command. The result stays the same.

On the serverside, we have the opportunity to limit the number of names
to return. However, this is not supported on the front end yet. My
proposal to use this ability: gitlab-org/gitlab-ce#42581. For now, this
ability is not used as that would change more behaviours on a feature
flag which might lead to unexpected changes on page refresh for example.
parent 498d3236
...@@ -721,11 +721,11 @@ class Repository ...@@ -721,11 +721,11 @@ class Repository
end end
def branch_names_contains(sha) def branch_names_contains(sha)
refs_contains_sha('branch', sha) raw_repository.branch_names_contains_sha(sha)
end end
def tag_names_contains(sha) def tag_names_contains(sha)
refs_contains_sha('tag', sha) raw_repository.tag_names_contains_sha(sha)
end end
def local_branches def local_branches
......
# Gitaly note: JV: no RPC's here.
module Gitlab module Gitlab
module Git module Git
class Branch < Ref class Branch < Ref
def self.find(repo, branch_name) class << self
def find(repo, branch_name)
if branch_name.is_a?(Gitlab::Git::Branch) if branch_name.is_a?(Gitlab::Git::Branch)
branch_name branch_name
else else
...@@ -11,6 +10,11 @@ module Gitlab ...@@ -11,6 +10,11 @@ module Gitlab
end end
end end
def names_contains_sha(repo, sha, limit: 0)
GitalyClient::RefService.new(repo).branch_names_contains_sha(sha)
end
end
def initialize(repository, name, target, target_commit) def initialize(repository, name, target, target_commit)
super(repository, name, target, target_commit) super(repository, name, target, target_commit)
end end
......
...@@ -1355,20 +1355,23 @@ module Gitlab ...@@ -1355,20 +1355,23 @@ module Gitlab
raise CommandError.new(e) raise CommandError.new(e)
end end
def refs_contains_sha(ref_type, sha) def branch_names_contains_sha(sha)
args = %W(#{ref_type} --contains #{sha}) gitaly_migrate(:branch_names_contains_sha) do |is_enabled|
names = run_git(args).first if is_enabled
Gitlab::Git::Branch.names_contains_sha(self, sha)
if names.respond_to?(:split) else
names = names.split("\n").map(&:strip) refs_contains_sha(:branch, sha)
end
names.each do |name| end
name.slice! '* '
end end
names def tag_names_contains_sha(sha)
gitaly_migrate(:tag_names_contains_sha) do |is_enabled|
if is_enabled
Gitlab::Git::Tag.names_contains_sha(self, sha)
else else
[] refs_contains_sha(:tag, sha)
end
end end
end end
...@@ -1446,6 +1449,21 @@ module Gitlab ...@@ -1446,6 +1449,21 @@ module Gitlab
end end
end end
def refs_contains_sha(ref_type, sha)
args = %W(#{ref_type} --contains #{sha})
names = run_git(args).first
return [] unless names.respond_to?(:split)
names = names.split("\n").map(&:strip)
names.each do |name|
name.slice! '* '
end
names
end
def shell_write_ref(ref_path, ref, old_ref) def shell_write_ref(ref_path, ref, old_ref)
raise ArgumentError, "invalid ref_path #{ref_path.inspect}" if ref_path.include?(' ') raise ArgumentError, "invalid ref_path #{ref_path.inspect}" if ref_path.include?(' ')
raise ArgumentError, "invalid ref #{ref.inspect}" if ref.include?("\x00") raise ArgumentError, "invalid ref #{ref.inspect}" if ref.include?("\x00")
......
# Gitaly note: JV: no RPC's here.
#
module Gitlab module Gitlab
module Git module Git
class Tag < Ref class Tag < Ref
class << self
def names_contains_sha(repo, sha)
GitalyClient::RefService.new(repo).branch_names_contains_sha(sha)
end
end
attr_reader :object_sha attr_reader :object_sha
def initialize(repository, name, target, target_commit, message = nil) def initialize(repository, name, target, target_commit, message = nil)
......
...@@ -145,6 +145,32 @@ module Gitlab ...@@ -145,6 +145,32 @@ module Gitlab
raise Gitlab::Git::Repository::GitError, response.git_error if response.git_error.present? raise Gitlab::Git::Repository::GitError, response.git_error if response.git_error.present?
end end
# Limit: 0 implies no limit, thus all tag names will be returned
def tag_names_containing(sha, limit: 0)
request = Gitaly::ListTagNamesContainingCommitRequest.new(
repository: @gitaly_repo,
commit_id: sha,
limit: limit
)
stream = GitalyClient.call(@repository.storage, :ref_service, :list_tag_names_containing_commit, request)
stream.each_with_object([]) { |response, array| array.concat(response.tag_names) }
end
# Limit: 0 implies no limit, thus all tag names will be returned
def branch_names_contains_sha(sha, limit: 0)
request = Gitaly::ListBranchNamesContainingCommitRequest.new(
repository: @gitaly_repo,
commit_id: sha,
limit: limit
)
stream = GitalyClient.call(@repository.storage, :ref_service, :list_branch_names_containing_commit, request)
stream.each_with_object([]) { |response, array| array.concat(response.branch_names) }
end
private private
def consume_refs_response(response) def consume_refs_response(response)
......
...@@ -36,6 +36,10 @@ describe Repository do ...@@ -36,6 +36,10 @@ describe Repository do
end end
describe '#branch_names_contains' do describe '#branch_names_contains' do
shared_examples '#branch_names_contains' do
set(:project) { create(:project, :repository) }
let(:repository) { project.repository }
subject { repository.branch_names_contains(sample_commit.id) } subject { repository.branch_names_contains(sample_commit.id) }
it { is_expected.to include('master') } it { is_expected.to include('master') }
...@@ -51,13 +55,32 @@ describe Repository do ...@@ -51,13 +55,32 @@ describe Repository do
end end
end end
context 'when gitaly is enabled' do
it_behaves_like '#branch_names_contains'
end
context 'when gitaly is disabled', :skip_gitaly_mock do
it_behaves_like '#branch_names_contains'
end
end
describe '#tag_names_contains' do describe '#tag_names_contains' do
shared_examples '#tag_names_contains' do
subject { repository.tag_names_contains(sample_commit.id) } subject { repository.tag_names_contains(sample_commit.id) }
it { is_expected.to include('v1.1.0') } it { is_expected.to include('v1.1.0') }
it { is_expected.not_to include('v1.0.0') } it { is_expected.not_to include('v1.0.0') }
end end
context 'when gitaly is enabled' do
it_behaves_like '#tag_names_contains'
end
context 'when gitaly is enabled', :skip_gitaly_mock do
it_behaves_like '#tag_names_contains'
end
end
describe 'tags_sorted_by' do describe 'tags_sorted_by' do
context 'name_desc' do context 'name_desc' do
subject { repository.tags_sorted_by('name_desc').map(&:name) } subject { repository.tags_sorted_by('name_desc').map(&:name) }
......
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