summaryrefslogtreecommitdiff
path: root/lib/gitlab/git
diff options
context:
space:
mode:
authorStan Hu <stanhu@gmail.com>2019-03-07 13:53:22 -0800
committerStan Hu <stanhu@gmail.com>2019-03-08 16:01:59 -0800
commit4ee08fd1f71caca88243833f08c2b1a59bd0fa9e (patch)
treea2af1a3f32a2dda7e208c9c1f8a6fb7c4672f9e0 /lib/gitlab/git
parent5566809c977ad6d61b6f16aad6135e6980e26b1f (diff)
downloadgitlab-ce-4ee08fd1f71caca88243833f08c2b1a59bd0fa9e.tar.gz
Add back Rugged support for retrieving a commit tree entry
This brings back some of the changes in https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/20176/diffs. We discovered another N+1 that hits Gitaly `TreeEntry` via the `RelativeLinkFilter`: https://gitlab.com/gitlab-org/gitlab-ce/issues/58657. When a blob is loaded with many relative links, `TreeEntry` is called for each link to scan the URI type. There are multiple paths that hit Gitaly `TreeEntry`, and https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/25706 did not cover all cases. This commit covers another common use case. For users using Gitaly on top of NFS, accessing the Git data directly via Rugged may be faster than going through than Gitaly. This merge request introduces the feature flag `rugged_commit_tree_entry` to activate the Rugged method.
Diffstat (limited to 'lib/gitlab/git')
-rw-r--r--lib/gitlab/git/commit.rb5
-rw-r--r--lib/gitlab/git/rugged_impl/commit.rb24
-rw-r--r--lib/gitlab/git/rugged_impl/repository.rb2
3 files changed, 30 insertions, 1 deletions
diff --git a/lib/gitlab/git/commit.rb b/lib/gitlab/git/commit.rb
index 491e4b47196..e5bbd500e98 100644
--- a/lib/gitlab/git/commit.rb
+++ b/lib/gitlab/git/commit.rb
@@ -314,11 +314,16 @@ module Gitlab
def tree_entry(path)
return unless path.present?
+ commit_tree_entry(path)
+ end
+
+ def commit_tree_entry(path)
# We're only interested in metadata, so limit actual data to 1 byte
# since Gitaly doesn't support "send no data" option.
entry = @repository.gitaly_commit_client.tree_entry(id, path, 1)
return unless entry
+ # To be compatible with the rugged format
entry = entry.to_h
entry.delete(:data)
entry[:name] = File.basename(path)
diff --git a/lib/gitlab/git/rugged_impl/commit.rb b/lib/gitlab/git/rugged_impl/commit.rb
index 251802878c3..f6777dfa0c3 100644
--- a/lib/gitlab/git/rugged_impl/commit.rb
+++ b/lib/gitlab/git/rugged_impl/commit.rb
@@ -43,6 +43,30 @@ module Gitlab
end
end
+ override :commit_tree_entry
+ def commit_tree_entry(path)
+ if Feature.enabled?(:rugged_commit_tree_entry)
+ rugged_tree_entry(path)
+ else
+ super
+ end
+ end
+
+ # Is this the same as Blob.find_entry_by_path ?
+ def rugged_tree_entry(path)
+ rugged_commit.tree.path(path)
+ rescue Rugged::TreeError
+ nil
+ end
+
+ def rugged_commit
+ @rugged_commit ||= if raw_commit.is_a?(Rugged::Commit)
+ raw_commit
+ else
+ @repository.rev_parse_target(id)
+ end
+ end
+
def init_from_rugged(commit)
author = commit.author
committer = commit.committer
diff --git a/lib/gitlab/git/rugged_impl/repository.rb b/lib/gitlab/git/rugged_impl/repository.rb
index fe0120b1199..c0a91f59ab9 100644
--- a/lib/gitlab/git/rugged_impl/repository.rb
+++ b/lib/gitlab/git/rugged_impl/repository.rb
@@ -12,7 +12,7 @@ module Gitlab
module Repository
extend ::Gitlab::Utils::Override
- FEATURE_FLAGS = %i(rugged_find_commit rugged_tree_entries rugged_tree_entry rugged_commit_is_ancestor).freeze
+ FEATURE_FLAGS = %i(rugged_find_commit rugged_tree_entries rugged_tree_entry rugged_commit_is_ancestor rugged_commit_tree_entry).freeze
def alternate_object_directories
relative_object_directories.map { |d| File.join(path, d) }