summaryrefslogtreecommitdiff
path: root/app/models/repository.rb
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-08-07 18:09:53 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-08-07 18:09:53 +0000
commit5edd0d173ff0bc377348bf3585fa309eee783e32 (patch)
treed71d995f018e56453e438f7b670c6597e45b4dd6 /app/models/repository.rb
parent61d62a296064e0330cffec7ed4b7914371b4984b (diff)
downloadgitlab-ce-5edd0d173ff0bc377348bf3585fa309eee783e32.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/models/repository.rb')
-rw-r--r--app/models/repository.rb27
1 files changed, 26 insertions, 1 deletions
diff --git a/app/models/repository.rb b/app/models/repository.rb
index f4244764338..9d876321217 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -43,7 +43,7 @@ class Repository
gitlab_ci_yml branch_names tag_names branch_count
tag_count avatar exists? root_ref merged_branch_names
has_visible_content? issue_template_names merge_request_template_names
- user_defined_metrics_dashboard_paths xcode_project?).freeze
+ user_defined_metrics_dashboard_paths xcode_project? has_ambiguous_refs?).freeze
# Methods that use cache_method but only memoize the value
MEMOIZED_CACHED_METHODS = %i(license).freeze
@@ -196,6 +196,31 @@ class Repository
tag_exists?(ref) && branch_exists?(ref)
end
+ # It's possible for a tag name to be a prefix (including slash) of a branch
+ # name, or vice versa. For instance, a tag named `foo` means we can't create a
+ # tag `foo/bar`, but we _can_ create a branch `foo/bar`.
+ #
+ # If we know a repository has no refs of this type (which is the common case)
+ # then separating refs from paths - as in ExtractsRef - can be faster.
+ #
+ # This method only checks one level deep, so only prefixes that contain no
+ # slashes are considered. If a repository has a tag `foo/bar` and a branch
+ # `foo/bar/baz`, it will return false.
+ def has_ambiguous_refs?
+ return false unless branch_names.present? && tag_names.present?
+
+ with_slash, no_slash = (branch_names + tag_names).partition { |ref| ref.include?('/') }
+
+ return false if with_slash.empty?
+
+ prefixes = no_slash.map { |ref| Regexp.escape(ref) }.join('|')
+ prefix_regex = %r{^#{prefixes}/}
+
+ with_slash.any? do |ref|
+ prefix_regex.match?(ref)
+ end
+ end
+
def expand_ref(ref)
if tag_exists?(ref)
Gitlab::Git::TAG_REF_PREFIX + ref