Commit bb746f7b 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 8f4b6e2e
......@@ -728,11 +728,11 @@ class Repository
end
def branch_names_contains(sha)
refs_contains_sha('branch', sha)
raw_repository.branch_names_contains_sha(sha)
end
def tag_names_contains(sha)
refs_contains_sha('tag', sha)
raw_repository.tag_names_contains_sha(sha)
end
def local_branches
......
# Gitaly note: JV: no RPC's here.
module Gitlab
module Git
class Branch < Ref
def self.find(repo, branch_name)
class << self
def find(repo, branch_name)
if branch_name.is_a?(Gitlab::Git::Branch)
branch_name
else
......@@ -11,6 +10,11 @@ module Gitlab
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)
super(repository, name, target, target_commit)
end
......
......@@ -1363,20 +1363,23 @@ module Gitlab
raise CommandError.new(e)
end
def refs_contains_sha(ref_type, sha)
args = %W(#{ref_type} --contains #{sha})
names = run_git(args).first
if names.respond_to?(:split)
names = names.split("\n").map(&:strip)
names.each do |name|
name.slice! '* '
def branch_names_contains_sha(sha)
gitaly_migrate(:branch_names_contains_sha) do |is_enabled|
if is_enabled
Gitlab::Git::Branch.names_contains_sha(self, sha)
else
refs_contains_sha(:branch, sha)
end
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
[]
refs_contains_sha(:tag, sha)
end
end
end
......@@ -1458,6 +1461,21 @@ module Gitlab
rugged.config['gitlab.fullpath'] = full_path
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)
raise ArgumentError, "invalid ref_path #{ref_path.inspect}" if ref_path.include?(' ')
raise ArgumentError, "invalid ref #{ref.inspect}" if ref.include?("\x00")
......
# Gitaly note: JV: no RPC's here.
#
module Gitlab
module Git
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
def initialize(repository, name, target, target_commit, message = nil)
......
......@@ -145,6 +145,32 @@ module Gitlab
raise Gitlab::Git::Repository::GitError, response.git_error if response.git_error.present?
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
def consume_refs_response(response)
......
......@@ -36,6 +36,10 @@ describe Repository do
end
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) }
it { is_expected.to include('master') }
......@@ -51,13 +55,32 @@ describe Repository do
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
shared_examples '#tag_names_contains' do
subject { repository.tag_names_contains(sample_commit.id) }
it { is_expected.to include('v1.1.0') }
it { is_expected.not_to include('v1.0.0') }
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
context 'name_desc' do
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