From 657065b73eb7253d60c9a63c74a75c0f9c3085ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kim=20=22BKC=22=20Carlb=C3=A4cker?= Date: Mon, 8 Jan 2018 16:24:59 +0100 Subject: [PATCH] Client-prep Gitlab::Git::Repository#write_ref --- app/models/project.rb | 2 +- app/models/repository.rb | 6 +----- lib/gitlab/git/repository.rb | 17 +++++++++++++++-- spec/models/project_spec.rb | 5 ++--- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/app/models/project.rb b/app/models/project.rb index fbe65e700a4..7dc5e980c1b 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1149,7 +1149,7 @@ class Project < ActiveRecord::Base def change_head(branch) if repository.branch_exists?(branch) repository.before_change_head - repository.write_ref('HEAD', "refs/heads/#{branch}") + repository.raw_repository.write_ref('HEAD', "refs/heads/#{branch}", shell: false) repository.copy_gitattributes(branch) repository.after_change_head reload_default_branch diff --git a/app/models/repository.rb b/app/models/repository.rb index 9c879e2006b..5fefdb5ef61 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -256,7 +256,7 @@ class Repository # This will still fail if the file is corrupted (e.g. 0 bytes) begin - write_ref(keep_around_ref_name(sha), sha) + raw_repository.write_ref(keep_around_ref_name(sha), sha, shell: false) rescue Rugged::ReferenceError => ex Rails.logger.error "Unable to create #{REF_KEEP_AROUND} reference for repository #{path}: #{ex}" rescue Rugged::OSError => ex @@ -270,10 +270,6 @@ class Repository ref_exists?(keep_around_ref_name(sha)) end - def write_ref(ref_path, sha) - rugged.references.create(ref_path, sha, force: true) - end - def diverging_commit_counts(branch) root_ref_hash = raw_repository.commit(root_ref).id cache.fetch(:"diverging_commit_counts_#{branch.name}") do diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index 283134e043e..fa9bc57dd79 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -1103,14 +1103,27 @@ module Gitlab end end - def write_ref(ref_path, ref) + def write_ref(ref_path, ref, old_ref: nil, shell: true) + if shell + shell_write_ref(ref_path, ref, old_ref) + else + rugged_write_ref(ref_path, ref) + end + 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") + raise ArgumentError, "invalid old_ref #{old_ref.inspect}" if !old_ref.nil? && old_ref.include?("\x00") - input = "update #{ref_path}\x00#{ref}\x00\x00" + input = "update #{ref_path}\x00#{ref}\x00#{old_ref}\x00" run_git!(%w[update-ref --stdin -z]) { |stdin| stdin.write(input) } end + def rugged_write_ref(ref_path, ref) + rugged.references.create(ref_path, ref, force: true) + end + def fetch_ref(source_repository, source_ref:, target_ref:) Gitlab::Git.check_namespace!(source_repository) source_repository = RemoteRepository.new(source_repository) unless source_repository.is_a?(RemoteRepository) diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 00afa09f1a3..78223c44999 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -1871,9 +1871,8 @@ describe Project do end it 'creates the new reference with rugged' do - expect(project.repository.rugged.references).to receive(:create).with('HEAD', - "refs/heads/#{project.default_branch}", - force: true) + expect(project.repository.raw_repository).to receive(:write_ref).with('HEAD', "refs/heads/#{project.default_branch}", shell: false) + project.change_head(project.default_branch) end