summaryrefslogtreecommitdiff
path: root/lib/gitlab/git/repository.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/git/repository.rb')
-rw-r--r--lib/gitlab/git/repository.rb103
1 files changed, 85 insertions, 18 deletions
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index d6c0980255f..5333766c338 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -133,7 +133,7 @@ module Gitlab
end
def exists?
- Gitlab::GitalyClient.migrate(:repository_exists) do |enabled|
+ Gitlab::GitalyClient.migrate(:repository_exists, status: Gitlab::GitalyClient::MigrationStatus::OPT_OUT) do |enabled|
if enabled
gitaly_repository_client.exists?
else
@@ -563,6 +563,8 @@ module Gitlab
return false if ancestor_id.nil? || descendant_id.nil?
merge_base_commit(ancestor_id, descendant_id) == ancestor_id
+ rescue Rugged::OdbError
+ false
end
# Returns true is +from+ is direct ancestor to +to+, otherwise false
@@ -1126,23 +1128,6 @@ module Gitlab
end
# Refactoring aid; allows us to copy code from app/models/repository.rb
- def run_git(args, chdir: path, env: {}, nice: false, &block)
- cmd = [Gitlab.config.git.bin_path, *args]
- cmd.unshift("nice") if nice
- circuit_breaker.perform do
- popen(cmd, chdir, env, &block)
- end
- end
-
- def run_git!(args, chdir: path, env: {}, nice: false, &block)
- output, status = run_git(args, chdir: chdir, env: env, nice: nice, &block)
-
- raise GitError, output unless status.zero?
-
- output
- end
-
- # Refactoring aid; allows us to copy code from app/models/repository.rb
def run_git_with_timeout(args, timeout, env: {})
circuit_breaker.perform do
popen_with_timeout([Gitlab.config.git.bin_path, *args], timeout, path, env)
@@ -1365,6 +1350,52 @@ module Gitlab
raise CommandError.new(e)
end
+ def refs_contains_sha(ref_type, sha)
+ args = %W(#{ref_type} --contains #{sha})
+ names = run_git(args).first
+
+ if names.respond_to?(:split)
+ names = names.split("\n").map(&:strip)
+
+ names.each do |name|
+ name.slice! '* '
+ end
+
+ names
+ else
+ []
+ end
+ end
+
+ def search_files_by_content(query, ref)
+ return [] if empty? || query.blank?
+
+ offset = 2
+ args = %W(grep -i -I -n -z --before-context #{offset} --after-context #{offset} -E -e #{Regexp.escape(query)} #{ref || root_ref})
+
+ run_git(args).first.scrub.split(/^--$/)
+ end
+
+ def search_files_by_name(query, ref)
+ safe_query = Regexp.escape(query.sub(/^\/*/, ""))
+
+ return [] if empty? || safe_query.blank?
+
+ args = %W(ls-tree --full-tree -r #{ref || root_ref} --name-status | #{safe_query})
+
+ run_git(args).first.lines.map(&:strip)
+ end
+
+ def find_commits_by_message(query, ref, path, limit, offset)
+ gitaly_migrate(:commits_by_message) do |is_enabled|
+ if is_enabled
+ find_commits_by_message_by_gitaly(query, ref, path, limit, offset)
+ else
+ find_commits_by_message_by_shelling_out(query, ref, path, limit, offset)
+ end
+ end
+ end
+
private
def shell_write_ref(ref_path, ref, old_ref)
@@ -1386,6 +1417,22 @@ module Gitlab
Rails.logger.error "Unable to create #{ref_path} reference for repository #{path}: #{ex}"
end
+ def run_git(args, chdir: path, env: {}, nice: false, &block)
+ cmd = [Gitlab.config.git.bin_path, *args]
+ cmd.unshift("nice") if nice
+ circuit_breaker.perform do
+ popen(cmd, chdir, env, &block)
+ end
+ end
+
+ def run_git!(args, chdir: path, env: {}, nice: false, &block)
+ output, status = run_git(args, chdir: chdir, env: env, nice: nice, &block)
+
+ raise GitError, output unless status.zero?
+
+ output
+ end
+
def fresh_worktree?(path)
File.exist?(path) && !clean_stuck_worktree(path)
end
@@ -2161,6 +2208,26 @@ module Gitlab
def gitlab_projects_error
raise CommandError, @gitlab_projects.output
end
+
+ def find_commits_by_message_by_shelling_out(query, ref, path, limit, offset)
+ ref ||= root_ref
+
+ args = %W(
+ log #{ref} --pretty=%H --skip #{offset}
+ --max-count #{limit} --grep=#{query} --regexp-ignore-case
+ )
+ args = args.concat(%W(-- #{path})) if path.present?
+
+ git_log_results = run_git(args).first.lines
+
+ git_log_results.map { |c| commit(c.chomp) }.compact
+ end
+
+ def find_commits_by_message_by_gitaly(query, ref, path, limit, offset)
+ gitaly_commit_client
+ .commits_by_message(query, revision: ref, path: path, limit: limit, offset: offset)
+ .map { |c| commit(c) }
+ end
end
end
end