Commit c5553ce7 authored by Lin Jen-Shin's avatar Lin Jen-Shin

Use `git update-ref --stdin -z` to delete refs

parent 86149a82
......@@ -1246,6 +1246,6 @@ def with_repo_tmp_commit(start_repository, start_branch_name, sha)
yield commit(sha)
ensure
rugged.references.delete(tmp_ref) if tmp_ref
delete_refs(tmp_ref) if tmp_ref
end
end
......@@ -9,7 +9,7 @@ def initialize(project)
def execute
Projects::HousekeepingService.new(@project).execute do
repository.delete_refs(garbage_refs)
repository.delete_refs(*garbage_refs)
end
rescue Projects::HousekeepingService::LeaseTaken => e
Rails.logger.info(
......
......@@ -17,6 +17,7 @@ class Repository
NoRepository = Class.new(StandardError)
InvalidBlobName = Class.new(StandardError)
InvalidRef = Class.new(StandardError)
GitError = Class.new(StandardError)
class << self
# Unlike `new`, `create` takes the storage path, not the storage name
......@@ -598,8 +599,21 @@ def delete_branch(branch_name)
rugged.branches.delete(branch_name)
end
def delete_refs(ref_names)
ref_names.each { |ref| rugged.references.delete(ref) }
def delete_refs(*ref_names)
instructions = ref_names.map do |ref|
"delete #{ref}\x00\x00"
end
command = %W[#{Gitlab.config.git.bin_path} update-ref --stdin -z]
message, status = Gitlab::Popen.popen(
command,
path) do |stdin|
stdin.write(instructions.join)
end
unless status.zero?
raise GitError.new("Could not delete refs #{ref_names}: #{message}")
end
end
# Create a new branch named **ref+ based on **stat_point+, HEAD by default
......
......@@ -111,7 +111,7 @@ namespace :gitlab do
next unless id > max_iid
project.deployments.find(id).create_ref
rugged.references.delete(ref)
project.repository.delete_refs(ref)
end
end
end
......
......@@ -433,6 +433,40 @@ def submodule_url(path)
end
end
describe '#delete_refs' do
before(:all) do
@repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '')
end
it 'deletes the ref' do
@repo.delete_refs('refs/heads/feature')
expect(@repo.rugged.references['refs/heads/feature']).to be_nil
end
it 'deletes all refs' do
refs = %w[refs/heads/wip refs/tags/v1.1.0]
@repo.delete_refs(*refs)
refs.each do |ref|
expect(@repo.rugged.references[ref]).to be_nil
end
end
it 'raises an error if it failed' do
expect(Gitlab::Popen).to receive(:popen).and_return(['Error', 1])
expect do
@repo.delete_refs('refs/heads/fix')
end.to raise_error(Gitlab::Git::Repository::GitError)
end
after(:all) do
FileUtils.rm_rf(TEST_MUTABLE_REPO_PATH)
ensure_seeds
end
end
describe "#refs_hash" do
let(:refs) { repository.refs_hash }
......
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