diff options
Diffstat (limited to 'spec/lib/gitlab/git/repository_spec.rb')
-rw-r--r-- | spec/lib/gitlab/git/repository_spec.rb | 291 |
1 files changed, 234 insertions, 57 deletions
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb index 0e4292026df..3cf165716bd 100644 --- a/spec/lib/gitlab/git/repository_spec.rb +++ b/spec/lib/gitlab/git/repository_spec.rb @@ -18,9 +18,10 @@ describe Gitlab::Git::Repository, seed_helper: true do end let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } + let(:storage_path) { TestEnv.repos_path } describe '.create_hooks' do - let(:repo_path) { File.join(TestEnv.repos_path, 'hook-test.git') } + let(:repo_path) { File.join(storage_path, 'hook-test.git') } let(:hooks_dir) { File.join(repo_path, 'hooks') } let(:target_hooks_dir) { Gitlab.config.gitlab_shell.hooks_path } let(:existing_target) { File.join(repo_path, 'foobar') } @@ -645,32 +646,42 @@ describe Gitlab::Git::Repository, seed_helper: true do end after do - Gitlab::Shell.new.remove_repository(TestEnv.repos_path, 'my_project') + Gitlab::Shell.new.remove_repository(storage_path, 'my_project') end - it 'fetches a repository as a mirror remote' do - subject + shared_examples 'repository mirror fecthing' do + it 'fetches a repository as a mirror remote' do + subject - expect(refs(new_repository.path)).to eq(refs(repository.path)) - end + expect(refs(new_repository.path)).to eq(refs(repository.path)) + end - context 'with keep-around refs' do - let(:sha) { SeedRepo::Commit::ID } - let(:keep_around_ref) { "refs/keep-around/#{sha}" } - let(:tmp_ref) { "refs/tmp/#{SecureRandom.hex}" } + context 'with keep-around refs' do + let(:sha) { SeedRepo::Commit::ID } + let(:keep_around_ref) { "refs/keep-around/#{sha}" } + let(:tmp_ref) { "refs/tmp/#{SecureRandom.hex}" } - before do - repository.rugged.references.create(keep_around_ref, sha, force: true) - repository.rugged.references.create(tmp_ref, sha, force: true) - end + before do + repository.rugged.references.create(keep_around_ref, sha, force: true) + repository.rugged.references.create(tmp_ref, sha, force: true) + end - it 'includes the temporary and keep-around refs' do - subject + it 'includes the temporary and keep-around refs' do + subject - expect(refs(new_repository.path)).to include(keep_around_ref) - expect(refs(new_repository.path)).to include(tmp_ref) + expect(refs(new_repository.path)).to include(keep_around_ref) + expect(refs(new_repository.path)).to include(tmp_ref) + end end end + + context 'with gitaly enabled' do + it_behaves_like 'repository mirror fecthing' + end + + context 'with gitaly enabled', :skip_gitaly_mock do + it_behaves_like 'repository mirror fecthing' + end end describe '#remote_tags' do @@ -1015,7 +1026,7 @@ describe Gitlab::Git::Repository, seed_helper: true do shared_examples 'extended commit counting' do context 'with after timestamp' do it 'returns the number of commits after timestamp' do - options = { ref: 'master', limit: nil, after: Time.iso8601('2013-03-03T20:15:01+00:00') } + options = { ref: 'master', after: Time.iso8601('2013-03-03T20:15:01+00:00') } expect(repository.count_commits(options)).to eq(25) end @@ -1023,19 +1034,65 @@ describe Gitlab::Git::Repository, seed_helper: true do context 'with before timestamp' do it 'returns the number of commits before timestamp' do - options = { ref: 'feature', limit: nil, before: Time.iso8601('2015-03-03T20:15:01+00:00') } + options = { ref: 'feature', before: Time.iso8601('2015-03-03T20:15:01+00:00') } expect(repository.count_commits(options)).to eq(9) end end + context 'with max_count' do + it 'returns the number of commits with path ' do + options = { ref: 'master', max_count: 5 } + + expect(repository.count_commits(options)).to eq(5) + end + end + context 'with path' do it 'returns the number of commits with path ' do - options = { ref: 'master', limit: nil, path: "encoding" } + options = { ref: 'master', path: 'encoding' } expect(repository.count_commits(options)).to eq(2) end end + + context 'with option :from and option :to' do + it 'returns the number of commits ahead for fix-mode..fix-blob-path' do + options = { from: 'fix-mode', to: 'fix-blob-path' } + + expect(repository.count_commits(options)).to eq(2) + end + + it 'returns the number of commits ahead for fix-blob-path..fix-mode' do + options = { from: 'fix-blob-path', to: 'fix-mode' } + + expect(repository.count_commits(options)).to eq(1) + end + + context 'with option :left_right' do + it 'returns the number of commits for fix-mode...fix-blob-path' do + options = { from: 'fix-mode', to: 'fix-blob-path', left_right: true } + + expect(repository.count_commits(options)).to eq([1, 2]) + end + + context 'with max_count' do + it 'returns the number of commits with path ' do + options = { from: 'fix-mode', to: 'fix-blob-path', left_right: true, max_count: 1 } + + expect(repository.count_commits(options)).to eq([1, 1]) + end + end + end + end + + context 'with max_count' do + it 'returns the number of commits up to the passed limit' do + options = { ref: 'master', max_count: 10, after: Time.iso8601('2013-03-03T20:15:01+00:00') } + + expect(repository.count_commits(options)).to eq(10) + end + end end context 'when Gitaly count_commits feature is enabled' do @@ -1047,14 +1104,6 @@ describe Gitlab::Git::Repository, seed_helper: true do end end - describe "branch_names_contains" do - subject { repository.branch_names_contains(SeedRepo::LastCommit::ID) } - - it { is_expected.to include('master') } - it { is_expected.not_to include('feature') } - it { is_expected.not_to include('fix') } - end - describe '#autocrlf' do before(:all) do @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') @@ -1226,48 +1275,58 @@ describe Gitlab::Git::Repository, seed_helper: true do end describe '#merged_branch_names' do - context 'when branch names are passed' do - it 'only returns the names we are asking' do - names = repository.merged_branch_names(%w[merge-test]) + shared_examples 'finding merged branch names' do + context 'when branch names are passed' do + it 'only returns the names we are asking' do + names = repository.merged_branch_names(%w[merge-test]) - expect(names).to contain_exactly('merge-test') - end + expect(names).to contain_exactly('merge-test') + end - it 'does not return unmerged branch names' do - names = repository.merged_branch_names(%w[feature]) + it 'does not return unmerged branch names' do + names = repository.merged_branch_names(%w[feature]) - expect(names).to be_empty + expect(names).to be_empty + end end - end - context 'when no root ref is available' do - it 'returns empty list' do - project = create(:project, :empty_repo) + context 'when no root ref is available' do + it 'returns empty list' do + project = create(:project, :empty_repo) - names = project.repository.merged_branch_names(%w[feature]) + names = project.repository.merged_branch_names(%w[feature]) - expect(names).to be_empty + expect(names).to be_empty + end end - end - context 'when no branch names are specified' do - before do - repository.create_branch('identical', 'master') - end + context 'when no branch names are specified' do + before do + repository.create_branch('identical', 'master') + end - after do - ensure_seeds - end + after do + ensure_seeds + end - it 'returns all merged branch names except for identical one' do - names = repository.merged_branch_names + it 'returns all merged branch names except for identical one' do + names = repository.merged_branch_names - expect(names).to include('merge-test') - expect(names).to include('fix-mode') - expect(names).not_to include('feature') - expect(names).not_to include('identical') + expect(names).to include('merge-test') + expect(names).to include('fix-mode') + expect(names).not_to include('feature') + expect(names).not_to include('identical') + end end end + + context 'when Gitaly merged_branch_names feature is enabled' do + it_behaves_like 'finding merged branch names' + end + + context 'when Gitaly merged_branch_names feature is disabled', :disable_gitaly do + it_behaves_like 'finding merged branch names' + end end describe "#ls_files" do @@ -1719,6 +1778,20 @@ describe Gitlab::Git::Repository, seed_helper: true do expect(result.repo_created).to eq(false) expect(result.branch_created).to eq(false) end + + it 'returns nil if there was a concurrent branch update' do + concurrent_update_id = '33f3729a45c02fc67d00adb1b8bca394b0e761d9' + result = repository.merge(user, source_sha, target_branch, 'Test merge') do + # This ref update should make the merge fail + repository.write_ref(Gitlab::Git::BRANCH_REF_PREFIX + target_branch, concurrent_update_id) + end + + # This 'nil' signals that the merge was not applied + expect(result).to be_nil + + # Our concurrent ref update should not have been undone + expect(repository.find_branch(target_branch).target).to eq(concurrent_update_id) + end end context 'with gitaly' do @@ -1884,6 +1957,110 @@ describe Gitlab::Git::Repository, seed_helper: true do end end + describe '#gitlab_projects' do + subject { repository.gitlab_projects } + + it { expect(subject.shard_path).to eq(storage_path) } + it { expect(subject.repository_relative_path).to eq(repository.relative_path) } + end + + context 'gitlab_projects commands' do + let(:gitlab_projects) { repository.gitlab_projects } + let(:timeout) { Gitlab.config.gitlab_shell.git_timeout } + + describe '#push_remote_branches' do + subject do + repository.push_remote_branches('downstream-remote', ['master']) + end + + it 'executes the command' do + expect(gitlab_projects).to receive(:push_branches) + .with('downstream-remote', timeout, true, ['master']) + .and_return(true) + + is_expected.to be_truthy + end + + it 'raises an error if the command fails' do + allow(gitlab_projects).to receive(:output) { 'error' } + expect(gitlab_projects).to receive(:push_branches) + .with('downstream-remote', timeout, true, ['master']) + .and_return(false) + + expect { subject }.to raise_error(Gitlab::Git::CommandError, 'error') + end + end + + describe '#delete_remote_branches' do + subject do + repository.delete_remote_branches('downstream-remote', ['master']) + end + + it 'executes the command' do + expect(gitlab_projects).to receive(:delete_remote_branches) + .with('downstream-remote', ['master']) + .and_return(true) + + is_expected.to be_truthy + end + + it 'raises an error if the command fails' do + allow(gitlab_projects).to receive(:output) { 'error' } + expect(gitlab_projects).to receive(:delete_remote_branches) + .with('downstream-remote', ['master']) + .and_return(false) + + expect { subject }.to raise_error(Gitlab::Git::CommandError, 'error') + end + end + + describe '#delete_remote_branches' do + subject do + repository.delete_remote_branches('downstream-remote', ['master']) + end + + it 'executes the command' do + expect(gitlab_projects).to receive(:delete_remote_branches) + .with('downstream-remote', ['master']) + .and_return(true) + + is_expected.to be_truthy + end + + it 'raises an error if the command fails' do + allow(gitlab_projects).to receive(:output) { 'error' } + expect(gitlab_projects).to receive(:delete_remote_branches) + .with('downstream-remote', ['master']) + .and_return(false) + + expect { subject }.to raise_error(Gitlab::Git::CommandError, 'error') + end + end + + describe '#delete_remote_branches' do + subject do + repository.delete_remote_branches('downstream-remote', ['master']) + end + + it 'executes the command' do + expect(gitlab_projects).to receive(:delete_remote_branches) + .with('downstream-remote', ['master']) + .and_return(true) + + is_expected.to be_truthy + end + + it 'raises an error if the command fails' do + allow(gitlab_projects).to receive(:output) { 'error' } + expect(gitlab_projects).to receive(:delete_remote_branches) + .with('downstream-remote', ['master']) + .and_return(false) + + expect { subject }.to raise_error(Gitlab::Git::CommandError, 'error') + end + end + end + def create_remote_branch(repository, remote_name, branch_name, source_branch_name) source_branch = repository.branches.find { |branch| branch.name == source_branch_name } rugged = repository.rugged |