diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index 508499f227c..fc9bcbdcca2 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -922,6 +922,12 @@ module Gitlab end end + def disconnect_alternates + wrapped_gitaly_errors do + gitaly_repository_client.disconnect_alternates + end + end + def gitaly_repository Gitlab::GitalyClient::Util.repository(@storage, @relative_path, @gl_repository, @gl_project_path) end diff --git a/lib/gitlab/gitaly_client/repository_service.rb b/lib/gitlab/gitaly_client/repository_service.rb index 74aae4a8e97..68b17e86608 100644 --- a/lib/gitlab/gitaly_client/repository_service.rb +++ b/lib/gitlab/gitaly_client/repository_service.rb @@ -331,6 +331,14 @@ module Gitlab search_results_from_response(response) end + def disconnect_alternates + request = Gitaly::DisconnectGitAlternatesRequest.new( + repository: @gitaly_repo + ) + + GitalyClient.call(@storage, :object_pool_service, :disconnect_git_alternates, request) + end + private def search_results_from_response(gitaly_response) diff --git a/spec/lib/gitlab/git/object_pool_spec.rb b/spec/lib/gitlab/git/object_pool_spec.rb index 6511c2b61bf..ebeb7b7b633 100644 --- a/spec/lib/gitlab/git/object_pool_spec.rb +++ b/spec/lib/gitlab/git/object_pool_spec.rb @@ -7,8 +7,6 @@ describe Gitlab::Git::ObjectPool do let(:pool_repository) { create(:pool_repository) } let(:source_repository) { pool_repository.source_project.repository } - let(:source_repository_path) { File.join(TestEnv.repos_path, source_repository.relative_path) } - let(:source_repository_rugged) { Rugged::Repository.new(source_repository_path) } subject { pool_repository.object_pool } @@ -82,6 +80,8 @@ describe Gitlab::Git::ObjectPool do end describe '#fetch' do + let(:source_repository_path) { File.join(TestEnv.repos_path, source_repository.relative_path) } + let(:source_repository_rugged) { Rugged::Repository.new(source_repository_path) } let(:commit_count) { source_repository.commit_count } context "when the object's pool repository exists" do @@ -98,7 +98,7 @@ describe Gitlab::Git::ObjectPool do it "re-creates the object pool's repository" do subject.fetch - expect(subject.repository.exists?).to be(true) + expect(subject.repository.exists?).to be true end it 'does not raise an error' do diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb index 0f6aac9b6de..7644d83992f 100644 --- a/spec/lib/gitlab/git/repository_spec.rb +++ b/spec/lib/gitlab/git/repository_spec.rb @@ -2215,4 +2215,43 @@ describe Gitlab::Git::Repository, :seed_helper do line.split("\t").last end end + + describe '#disconnect_alternates' do + let(:project) { create(:project, :repository) } + let(:pool_repository) { create(:pool_repository) } + let(:repository) { project.repository } + let(:repository_path) { File.join(TestEnv.repos_path, repository.relative_path) } + let(:object_pool) { pool_repository.object_pool } + let(:object_pool_path) { File.join(TestEnv.repos_path, object_pool.repository.relative_path) } + let(:object_pool_rugged) { Rugged::Repository.new(object_pool_path) } + + before do + object_pool.create + end + + it 'does not raise an error when disconnecting a non-linked repository' do + expect { repository.disconnect_alternates }.not_to raise_error + end + + it 'removes the alternates file' do + object_pool.link(repository) + + alternates_file = File.join(repository_path, "objects", "info", "alternates") + expect(File.exist?(alternates_file)).to be_truthy + + repository.disconnect_alternates + + expect(File.exist?(alternates_file)).to be_falsey + end + + it 'can still access objects in the object pool' do + object_pool.link(repository) + new_commit = new_commit_edit_old_file(object_pool_rugged) + expect(repository.commit(new_commit.oid).id).to eq(new_commit.oid) + + repository.disconnect_alternates + + expect(repository.commit(new_commit.oid).id).to eq(new_commit.oid) + end + end end diff --git a/spec/lib/gitlab/gitaly_client/repository_service_spec.rb b/spec/lib/gitlab/gitaly_client/repository_service_spec.rb index 46ca2340389..09de7ca6afd 100644 --- a/spec/lib/gitlab/gitaly_client/repository_service_spec.rb +++ b/spec/lib/gitlab/gitaly_client/repository_service_spec.rb @@ -231,4 +231,34 @@ describe Gitlab::GitalyClient::RepositoryService do client.raw_changes_between('deadbeef', 'deadpork') end end + + describe '#disconnect_alternates' do + let(:project) { create(:project, :repository) } + let(:repository) { project.repository } + let(:repository_path) { File.join(TestEnv.repos_path, repository.relative_path) } + let(:pool_repository) { create(:pool_repository) } + let(:object_pool) { pool_repository.object_pool } + let(:object_pool_service) { Gitlab::GitalyClient::ObjectPoolService.new(object_pool) } + + before do + object_pool_service.create(repository) + object_pool_service.link_repository(repository) + end + + it 'deletes the alternates file' do + repository.disconnect_alternates + + alternates_file = File.join(repository_path, "objects", "info", "alternates") + + expect(File.exist?(alternates_file)).to be_falsey + end + + context 'when called twice' do + it "doesn't raise an error" do + repository.disconnect_alternates + + expect { repository.disconnect_alternates }.not_to raise_error + end + end + end end