From e70fe78281ba07d9a0eb863d66ddf6a13917fde1 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Tue, 20 Feb 2018 09:06:00 +0100 Subject: [PATCH] Handle branch and tag names which are commit ids Adds a test where a branch name is also a valid commit id. Git, the binary should create an error message which is difficult to parse and leading to errors later, as seen in: gitlab-org/gitlab-ce#43222 To catch these cases in the future, gitlab-test@1942eed5cc108b19c7405106e81fa96125d0be22 was created. Which a branch name matching the commit --- .../zj-branch-contains-git-message.yml | 5 ++++ lib/gitlab/git/repository.rb | 26 +++++++++++------- spec/lib/gitlab/git/repository_spec.rb | 27 +++++++++++++++++++ 3 files changed, 48 insertions(+), 10 deletions(-) create mode 100644 changelogs/unreleased/zj-branch-contains-git-message.yml diff --git a/changelogs/unreleased/zj-branch-contains-git-message.yml b/changelogs/unreleased/zj-branch-contains-git-message.yml new file mode 100644 index 00000000000..ce034e7ec87 --- /dev/null +++ b/changelogs/unreleased/zj-branch-contains-git-message.yml @@ -0,0 +1,5 @@ +--- +title: Allow branch names to be named the same as the sha it points to +merge_request: +author: +type: fixed diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index a10bc0dd32b..072ad312ab8 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -1349,7 +1349,7 @@ module Gitlab if is_enabled gitaly_ref_client.branch_names_contains_sha(sha) else - refs_contains_sha(:branch, sha) + refs_contains_sha('refs/heads/', sha) end end end @@ -1359,7 +1359,7 @@ module Gitlab if is_enabled gitaly_ref_client.tag_names_contains_sha(sha) else - refs_contains_sha(:tag, sha) + refs_contains_sha('refs/tags/', sha) end end end @@ -1458,19 +1458,25 @@ module Gitlab end end - def refs_contains_sha(ref_type, sha) - args = %W(#{ref_type} --contains #{sha}) - names = run_git(args).first + def refs_contains_sha(refs_prefix, sha) + refs_prefix << "/" unless refs_prefix.ends_with?('/') - return [] unless names.respond_to?(:split) + # By forcing the output to %(refname) each line wiht a ref will start with + # the ref prefix. All other lines can be discarded. + args = %W(for-each-ref --contains=#{sha} --format=%(refname) #{refs_prefix}) + names, code = run_git(args) - names = names.split("\n").map(&:strip) + return [] unless code.zero? - names.each do |name| - name.slice! '* ' + refs = [] + left_slice_count = refs_prefix.length + names.lines.each do |line| + next unless line.start_with?(refs_prefix) + + refs << line.rstrip[left_slice_count..-1] end - names + refs end def rugged_write_config(full_path:) diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb index 0e9150964fa..9feaaec3f3b 100644 --- a/spec/lib/gitlab/git/repository_spec.rb +++ b/spec/lib/gitlab/git/repository_spec.rb @@ -600,6 +600,33 @@ describe Gitlab::Git::Repository, seed_helper: true do end end + describe '#branch_names_contains_sha' do + shared_examples 'returning the right branches' do + let(:head_id) { repository.rugged.head.target.oid } + let(:new_branch) { head_id } + + before do + repository.create_branch(new_branch, 'master') + end + + after do + repository.delete_branch(new_branch) + end + + it 'displays that branch' do + expect(repository.branch_names_contains_sha(head_id)).to include('master', new_branch) + end + end + + context 'when Gitaly is enabled' do + it_behaves_like 'returning the right branches' + end + + context 'when Gitaly is disabled', :disable_gitaly do + it_behaves_like 'returning the right branches' + end + end + describe "#refs_hash" do subject { repository.refs_hash } -- GitLab