Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib/gitlab/git/repository_spec.rb')
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb475
1 files changed, 135 insertions, 340 deletions
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index 703b0c2c202..50736d353ad 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -3,6 +3,20 @@ require "spec_helper"
describe Gitlab::Git::Repository, seed_helper: true do
include Gitlab::EncodingHelper
+ shared_examples 'wrapping gRPC errors' do |gitaly_client_class, gitaly_client_method|
+ it 'wraps gRPC not found error' do
+ expect_any_instance_of(gitaly_client_class).to receive(gitaly_client_method)
+ .and_raise(GRPC::NotFound)
+ expect { subject }.to raise_error(Gitlab::Git::Repository::NoRepository)
+ end
+
+ it 'wraps gRPC unknown error' do
+ expect_any_instance_of(gitaly_client_class).to receive(gitaly_client_method)
+ .and_raise(GRPC::Unknown)
+ expect { subject }.to raise_error(Gitlab::Git::CommandError)
+ end
+ end
+
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
describe "Respond to" do
@@ -26,31 +40,17 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
end
- context 'with gitaly enabled' do
- before do
- stub_gitaly
- end
-
- after do
- Gitlab::GitalyClient.clear_stubs!
- end
-
- it 'gets the branch name from GitalyClient' do
- expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:default_branch_name)
- repository.root_ref
- end
+ it 'returns UTF-8' do
+ expect(repository.root_ref).to be_utf8
+ end
- it 'wraps GRPC not found' do
- expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:default_branch_name)
- .and_raise(GRPC::NotFound)
- expect { repository.root_ref }.to raise_error(Gitlab::Git::Repository::NoRepository)
- end
+ it 'gets the branch name from GitalyClient' do
+ expect_any_instance_of(Gitlab::GitalyClient::RefService).to receive(:default_branch_name)
+ repository.root_ref
+ end
- it 'wraps GRPC exceptions' do
- expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:default_branch_name)
- .and_raise(GRPC::Unknown)
- expect { repository.root_ref }.to raise_error(Gitlab::Git::CommandError)
- end
+ it_behaves_like 'wrapping gRPC errors', Gitlab::GitalyClient::RefService, :default_branch_name do
+ subject { repository.root_ref }
end
end
@@ -123,45 +123,35 @@ describe Gitlab::Git::Repository, seed_helper: true do
it 'has SeedRepo::Repo::BRANCHES.size elements' do
expect(subject.size).to eq(SeedRepo::Repo::BRANCHES.size)
end
- it { is_expected.to include("master") }
- it { is_expected.not_to include("branch-from-space") }
- context 'with gitaly enabled' do
- before do
- stub_gitaly
- end
-
- after do
- Gitlab::GitalyClient.clear_stubs!
- end
-
- it 'gets the branch names from GitalyClient' do
- expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:branch_names)
- subject
- end
+ it 'returns UTF-8' do
+ expect(subject.first).to be_utf8
+ end
- it 'wraps GRPC not found' do
- expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:branch_names)
- .and_raise(GRPC::NotFound)
- expect { subject }.to raise_error(Gitlab::Git::Repository::NoRepository)
- end
+ it { is_expected.to include("master") }
+ it { is_expected.not_to include("branch-from-space") }
- it 'wraps GRPC other exceptions' do
- expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:branch_names)
- .and_raise(GRPC::Unknown)
- expect { subject }.to raise_error(Gitlab::Git::CommandError)
- end
+ it 'gets the branch names from GitalyClient' do
+ expect_any_instance_of(Gitlab::GitalyClient::RefService).to receive(:branch_names)
+ subject
end
+
+ it_behaves_like 'wrapping gRPC errors', Gitlab::GitalyClient::RefService, :branch_names
end
describe '#tag_names' do
subject { repository.tag_names }
it { is_expected.to be_kind_of Array }
+
it 'has SeedRepo::Repo::TAGS.size elements' do
expect(subject.size).to eq(SeedRepo::Repo::TAGS.size)
end
+ it 'returns UTF-8' do
+ expect(subject.first).to be_utf8
+ end
+
describe '#last' do
subject { super().last }
it { is_expected.to eq("v1.2.1") }
@@ -169,32 +159,12 @@ describe Gitlab::Git::Repository, seed_helper: true do
it { is_expected.to include("v1.0.0") }
it { is_expected.not_to include("v5.0.0") }
- context 'with gitaly enabled' do
- before do
- stub_gitaly
- end
-
- after do
- Gitlab::GitalyClient.clear_stubs!
- end
-
- it 'gets the tag names from GitalyClient' do
- expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:tag_names)
- subject
- end
-
- it 'wraps GRPC not found' do
- expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:tag_names)
- .and_raise(GRPC::NotFound)
- expect { subject }.to raise_error(Gitlab::Git::Repository::NoRepository)
- end
-
- it 'wraps GRPC exceptions' do
- expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:tag_names)
- .and_raise(GRPC::Unknown)
- expect { subject }.to raise_error(Gitlab::Git::CommandError)
- end
+ it 'gets the tag names from GitalyClient' do
+ expect_any_instance_of(Gitlab::GitalyClient::RefService).to receive(:tag_names)
+ subject
end
+
+ it_behaves_like 'wrapping gRPC errors', Gitlab::GitalyClient::RefService, :tag_names
end
shared_examples 'archive check' do |extenstion|
@@ -264,33 +234,6 @@ describe Gitlab::Git::Repository, seed_helper: true do
it { expect(repository.bare?).to be_truthy }
end
- describe '#heads' do
- let(:heads) { repository.heads }
- subject { heads }
-
- it { is_expected.to be_kind_of Array }
-
- describe '#size' do
- subject { super().size }
- it { is_expected.to eq(SeedRepo::Repo::BRANCHES.size) }
- end
-
- context :head do
- subject { heads.first }
-
- describe '#name' do
- subject { super().name }
- it { is_expected.to eq("feature") }
- end
-
- context :commit do
- subject { heads.first.dereferenced_target.sha }
-
- it { is_expected.to eq("0b4bc9a49b562e85de7cc9e834518ea6828729b9") }
- end
- end
- end
-
describe '#ref_names' do
let(:ref_names) { repository.ref_names }
subject { ref_names }
@@ -308,39 +251,35 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
end
- describe '#search_files' do
- let(:results) { repository.search_files('rails', 'master') }
- subject { results }
-
- it { is_expected.to be_kind_of Array }
+ describe '#submodule_url_for' do
+ let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
+ let(:ref) { 'master' }
- describe '#first' do
- subject { super().first }
- it { is_expected.to be_kind_of Gitlab::Git::BlobSnippet }
+ def submodule_url(path)
+ repository.submodule_url_for(ref, path)
end
- context 'blob result' do
- subject { results.first }
+ it { expect(submodule_url('six')).to eq('git://github.com/randx/six.git') }
+ it { expect(submodule_url('nested/six')).to eq('git://github.com/randx/six.git') }
+ it { expect(submodule_url('deeper/nested/six')).to eq('git://github.com/randx/six.git') }
+ it { expect(submodule_url('invalid/path')).to eq(nil) }
- describe '#ref' do
- subject { super().ref }
- it { is_expected.to eq('master') }
- end
+ context 'uncommitted submodule dir' do
+ let(:ref) { 'fix-existing-submodule-dir' }
- describe '#filename' do
- subject { super().filename }
- it { is_expected.to eq('CHANGELOG') }
- end
+ it { expect(submodule_url('submodule-existing-dir')).to eq(nil) }
+ end
- describe '#startline' do
- subject { super().startline }
- it { is_expected.to eq(35) }
- end
+ context 'tags' do
+ let(:ref) { 'v1.2.1' }
- describe '#data' do
- subject { super().data }
- it { is_expected.to include "Ability to filter by multiple labels" }
- end
+ it { expect(submodule_url('six')).to eq('git://github.com/randx/six.git') }
+ end
+
+ context 'no submodules at commit' do
+ let(:ref) { '6d39438' }
+
+ it { expect(submodule_url('six')).to eq(nil) }
end
end
@@ -348,7 +287,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
context 'where repo has submodules' do
- let(:submodules) { repository.submodules('master') }
+ let(:submodules) { repository.send(:submodules, 'master') }
let(:submodule) { submodules.first }
it { expect(submodules).to be_kind_of Hash }
@@ -383,12 +322,12 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
it 'should not have an entry for an uncommited submodule dir' do
- submodules = repository.submodules('fix-existing-submodule-dir')
+ submodules = repository.send(:submodules, 'fix-existing-submodule-dir')
expect(submodules).not_to have_key('submodule-existing-dir')
end
it 'should handle tags correctly' do
- submodules = repository.submodules('v1.2.1')
+ submodules = repository.send(:submodules, 'v1.2.1')
expect(submodules.first).to eq([
"six", {
@@ -414,7 +353,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
context 'where repo doesn\'t have submodules' do
- let(:submodules) { repository.submodules('6d39438') }
+ let(:submodules) { repository.send(:submodules, '6d39438') }
it 'should return an empty hash' do
expect(submodules).to be_empty
end
@@ -422,145 +361,20 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
describe '#commit_count' do
- it { expect(repository.commit_count("master")).to eq(25) }
- it { expect(repository.commit_count("feature")).to eq(9) }
- end
-
- describe "#reset" do
- change_path = File.join(SEED_STORAGE_PATH, TEST_NORMAL_REPO_PATH, "CHANGELOG")
- untracked_path = File.join(SEED_STORAGE_PATH, TEST_NORMAL_REPO_PATH, "UNTRACKED")
- tracked_path = File.join(SEED_STORAGE_PATH, TEST_NORMAL_REPO_PATH, "files", "ruby", "popen.rb")
-
- change_text = "New changelog text"
- untracked_text = "This file is untracked"
-
- reset_commit = SeedRepo::LastCommit::ID
-
- context "--hard" do
- before(:all) do
- # Modify a tracked file
- File.open(change_path, "w") do |f|
- f.write(change_text)
- end
-
- # Add an untracked file to the working directory
- File.open(untracked_path, "w") do |f|
- f.write(untracked_text)
- end
-
- @normal_repo = Gitlab::Git::Repository.new('default', TEST_NORMAL_REPO_PATH)
- @normal_repo.reset("HEAD", :hard)
- end
-
- it "should replace the working directory with the content of the index" do
- File.open(change_path, "r") do |f|
- expect(f.each_line.first).not_to eq(change_text)
- end
-
- File.open(tracked_path, "r") do |f|
- expect(f.each_line.to_a[8]).to include('raise RuntimeError, "System commands')
- end
- end
-
- it "should not touch untracked files" do
- expect(File.exist?(untracked_path)).to be_truthy
- end
-
- it "should move the HEAD to the correct commit" do
- new_head = @normal_repo.rugged.head.target.oid
- expect(new_head).to eq(reset_commit)
- end
-
- it "should move the tip of the master branch to the correct commit" do
- new_tip = @normal_repo.rugged.references["refs/heads/master"]
- .target.oid
-
- expect(new_tip).to eq(reset_commit)
- end
-
- after(:all) do
- # Fast-forward to the original HEAD
- FileUtils.rm_rf(TEST_NORMAL_REPO_PATH)
- ensure_seeds
- end
+ shared_examples 'counting commits' do
+ it { expect(repository.commit_count("master")).to eq(25) }
+ it { expect(repository.commit_count("feature")).to eq(9) }
end
- end
-
- describe "#checkout" do
- new_branch = "foo_branch"
-
- context "-b" do
- before(:all) do
- @normal_repo = Gitlab::Git::Repository.new('default', TEST_NORMAL_REPO_PATH)
- @normal_repo.checkout(new_branch, { b: true }, "origin/feature")
- end
- it "should create a new branch" do
- expect(@normal_repo.rugged.branches[new_branch]).not_to be_nil
- end
-
- it "should move the HEAD to the correct commit" do
- expect(@normal_repo.rugged.head.target.oid).to(
- eq(@normal_repo.rugged.branches["origin/feature"].target.oid)
- )
- end
-
- it "should refresh the repo's #heads collection" do
- head_names = @normal_repo.heads.map { |h| h.name }
- expect(head_names).to include(new_branch)
- end
-
- after(:all) do
- FileUtils.rm_rf(TEST_NORMAL_REPO_PATH)
- ensure_seeds
+ context 'when Gitaly commit_count feature is enabled' do
+ it_behaves_like 'counting commits'
+ it_behaves_like 'wrapping gRPC errors', Gitlab::GitalyClient::CommitService, :commit_count do
+ subject { repository.commit_count('master') }
end
end
- context "without -b" do
- context "and specifying a nonexistent branch" do
- it "should not do anything" do
- normal_repo = Gitlab::Git::Repository.new('default', TEST_NORMAL_REPO_PATH)
-
- expect { normal_repo.checkout(new_branch) }.to raise_error(Rugged::ReferenceError)
- expect(normal_repo.rugged.branches[new_branch]).to be_nil
- expect(normal_repo.rugged.head.target.oid).to(
- eq(normal_repo.rugged.branches["master"].target.oid)
- )
-
- head_names = normal_repo.heads.map { |h| h.name }
- expect(head_names).not_to include(new_branch)
- end
-
- after(:all) do
- FileUtils.rm_rf(TEST_NORMAL_REPO_PATH)
- ensure_seeds
- end
- end
-
- context "and with a valid branch" do
- before(:all) do
- @normal_repo = Gitlab::Git::Repository.new('default', TEST_NORMAL_REPO_PATH)
- @normal_repo.rugged.branches.create("feature", "origin/feature")
- @normal_repo.checkout("feature")
- end
-
- it "should move the HEAD to the correct commit" do
- expect(@normal_repo.rugged.head.target.oid).to(
- eq(@normal_repo.rugged.branches["feature"].target.oid)
- )
- end
-
- it "should update the working directory" do
- File.open(File.join(SEED_STORAGE_PATH, TEST_NORMAL_REPO_PATH, ".gitignore"), "r") do |f|
- expect(f.read.each_line.to_a).not_to include(".DS_Store\n")
- end
- end
-
- after(:all) do
- FileUtils.rm_rf(SEED_STORAGE_PATH, TEST_NORMAL_REPO_PATH)
- ensure_seeds
- end
- end
+ context 'when Gitaly commit_count feature is disabled', skip_gitaly_mock: true do
+ it_behaves_like 'counting commits'
end
end
@@ -574,10 +388,6 @@ describe Gitlab::Git::Repository, seed_helper: true do
expect(@repo.rugged.branches["feature"]).to be_nil
end
- it "should update the repo's #heads collection" do
- expect(@repo.heads).not_to include("feature")
- end
-
after(:all) do
FileUtils.rm_rf(TEST_MUTABLE_REPO_PATH)
ensure_seeds
@@ -690,9 +500,9 @@ describe Gitlab::Git::Repository, seed_helper: true do
# Add new commits so that there's a renamed file in the commit history
repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH).rugged
- commit_with_old_name = new_commit_edit_old_file(repo)
- rename_commit = new_commit_move_file(repo)
- commit_with_new_name = new_commit_edit_new_file(repo)
+ commit_with_old_name = Gitlab::Git::Commit.decorate(new_commit_edit_old_file(repo))
+ rename_commit = Gitlab::Git::Commit.decorate(new_commit_move_file(repo))
+ commit_with_new_name = Gitlab::Git::Commit.decorate(new_commit_edit_new_file(repo))
end
after(:context) do
@@ -865,8 +675,8 @@ describe Gitlab::Git::Repository, seed_helper: true do
context "compare results between log_by_walk and log_by_shell" do
let(:options) { { ref: "master" } }
- let(:commits_by_walk) { repository.log(options).map(&:oid) }
- let(:commits_by_shell) { repository.log(options.merge({ disable_walk: true })).map(&:oid) }
+ let(:commits_by_walk) { repository.log(options).map(&:id) }
+ let(:commits_by_shell) { repository.log(options.merge({ disable_walk: true })).map(&:id) }
it { expect(commits_by_walk).to eq(commits_by_shell) }
@@ -909,7 +719,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
expect(commits.size).to be > 0
expect(commits).to satisfy do |commits|
- commits.all? { |commit| commit.time >= options[:after] }
+ commits.all? { |commit| commit.committed_date >= options[:after] }
end
end
end
@@ -922,7 +732,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
expect(commits.size).to be > 0
expect(commits).to satisfy do |commits|
- commits.all? { |commit| commit.time <= options[:before] }
+ commits.all? { |commit| commit.committed_date <= options[:before] }
end
end
end
@@ -931,7 +741,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
let(:options) { { ref: 'master', path: ['PROCESS.md', 'README.md'] } }
def commit_files(commit)
- commit.diff(commit.parent_ids.first).deltas.flat_map do |delta|
+ commit.diff_from_parent.deltas.flat_map do |delta|
[delta.old_file[:path], delta.new_file[:path]].uniq.compact
end
end
@@ -1101,48 +911,49 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
end
- describe '#find_commits' do
- it 'should return a return a collection of commits' do
- commits = repository.find_commits
+ describe '#branches' do
+ subject { repository.branches }
- expect(commits).not_to be_empty
- expect(commits).to all( be_a_kind_of(Gitlab::Git::Commit) )
- end
+ context 'with local and remote branches' do
+ let(:repository) do
+ Gitlab::Git::Repository.new('default', File.join(TEST_MUTABLE_REPO_PATH, '.git'))
+ end
- context 'while applying a sort order based on the `order` option' do
- it "allows ordering topologically (no parents shown before their children)" do
- expect_any_instance_of(Rugged::Walker).to receive(:sorting).with(Rugged::SORT_TOPO)
+ before do
+ create_remote_branch(repository, 'joe', 'remote_branch', 'master')
+ repository.create_branch('local_branch', 'master')
+ end
- repository.find_commits(order: :topo)
+ after do
+ FileUtils.rm_rf(TEST_MUTABLE_REPO_PATH)
+ ensure_seeds
end
- it "allows ordering by date" do
- expect_any_instance_of(Rugged::Walker).to receive(:sorting).with(Rugged::SORT_DATE | Rugged::SORT_TOPO)
+ it 'returns the local and remote branches' do
+ expect(subject.any? { |b| b.name == 'joe/remote_branch' }).to eq(true)
+ expect(subject.any? { |b| b.name == 'local_branch' }).to eq(true)
+ end
+ end
- repository.find_commits(order: :date)
+ # With Gitaly enabled, Gitaly just doesn't return deleted branches.
+ context 'with deleted branch with Gitaly disabled' do
+ before do
+ allow(Gitlab::GitalyClient).to receive(:feature_enabled?).and_return(false)
end
- it "applies no sorting by default" do
- expect_any_instance_of(Rugged::Walker).to receive(:sorting).with(Rugged::SORT_NONE)
+ it 'returns no results' do
+ ref = double()
+ allow(ref).to receive(:name) { 'bad-branch' }
+ allow(ref).to receive(:target) { raise Rugged::ReferenceError }
+ branches = double()
+ allow(branches).to receive(:each) { [ref].each }
+ allow(repository.rugged).to receive(:branches) { branches }
- repository.find_commits
+ expect(subject).to be_empty
end
end
- end
-
- describe '#branches with deleted branch' do
- before(:each) do
- ref = double()
- allow(ref).to receive(:name) { 'bad-branch' }
- allow(ref).to receive(:target) { raise Rugged::ReferenceError }
- branches = double()
- allow(branches).to receive(:each) { [ref].each }
- allow(repository.rugged).to receive(:branches) { branches }
- end
- it 'should return empty branches' do
- expect(repository.branches).to eq([])
- end
+ it_behaves_like 'wrapping gRPC errors', Gitlab::GitalyClient::RefService, :branches
end
describe '#branch_count' do
@@ -1289,45 +1100,36 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
it 'returns the local branches' do
- create_remote_branch('joe', 'remote_branch', 'master')
+ create_remote_branch(@repo, 'joe', 'remote_branch', 'master')
@repo.create_branch('local_branch', 'master')
expect(@repo.local_branches.any? { |branch| branch.name == 'remote_branch' }).to eq(false)
expect(@repo.local_branches.any? { |branch| branch.name == 'local_branch' }).to eq(true)
end
- context 'with gitaly enabled' do
- before do
- stub_gitaly
- end
-
- after do
- Gitlab::GitalyClient.clear_stubs!
- end
-
- it 'gets the branches from GitalyClient' do
- expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:local_branches)
- .and_return([])
- @repo.local_branches
+ it 'returns a Branch with UTF-8 fields' do
+ branches = @repo.local_branches.to_a
+ expect(branches.size).to be > 0
+ branches.each do |branch|
+ expect(branch.name).to be_utf8
+ expect(branch.target).to be_utf8 unless branch.target.nil?
end
+ end
- it 'wraps GRPC not found' do
- expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:local_branches)
- .and_raise(GRPC::NotFound)
- expect { @repo.local_branches }.to raise_error(Gitlab::Git::Repository::NoRepository)
- end
+ it 'gets the branches from GitalyClient' do
+ expect_any_instance_of(Gitlab::GitalyClient::RefService).to receive(:local_branches)
+ .and_return([])
+ @repo.local_branches
+ end
- it 'wraps GRPC exceptions' do
- expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:local_branches)
- .and_raise(GRPC::Unknown)
- expect { @repo.local_branches }.to raise_error(Gitlab::Git::CommandError)
- end
+ it_behaves_like 'wrapping gRPC errors', Gitlab::GitalyClient::RefService, :local_branches do
+ subject { @repo.local_branches }
end
end
- def create_remote_branch(remote_name, branch_name, source_branch_name)
- source_branch = @repo.branches.find { |branch| branch.name == source_branch_name }
- rugged = @repo.rugged
+ 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
rugged.references.create("refs/remotes/#{remote_name}/#{branch_name}", source_branch.dereferenced_target.sha)
end
@@ -1400,11 +1202,4 @@ describe Gitlab::Git::Repository, seed_helper: true do
sha = Rugged::Commit.create(repo, options)
repo.lookup(sha)
end
-
- def stub_gitaly
- allow(Gitlab::GitalyClient).to receive(:feature_enabled?).and_return(true)
-
- stub = double(:stub)
- allow(Gitaly::Ref::Stub).to receive(:new).and_return(stub)
- end
end