summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZeger-Jan van de Weg <git@zjvandeweg.nl>2018-02-20 09:06:00 +0100
committerZeger-Jan van de Weg <git@zjvandeweg.nl>2018-02-21 19:08:26 +0100
commite70fe78281ba07d9a0eb863d66ddf6a13917fde1 (patch)
tree9a182fa06fdb2555d8ca1238d7e960ec7e0a6ade
parent9ff91bc481683e3619e0745b03161a12a5afd497 (diff)
downloadgitlab-ce-e70fe78281ba07d9a0eb863d66ddf6a13917fde1.tar.gz
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
-rw-r--r--changelogs/unreleased/zj-branch-contains-git-message.yml5
-rw-r--r--lib/gitlab/git/repository.rb26
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb27
3 files changed, 48 insertions, 10 deletions
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 }