Skip to content
Snippets Groups Projects
Commit 9d3e413a authored by Stan Hu's avatar Stan Hu
Browse files

Bring back Rugged implementation of TreeEntry

This brings back some of the changes in
https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/20099/diffs

For users using Gitaly on top of NFS, accessing the Git data directly
via Rugged is more performant than Gitaly. This merge request introduces
the feature flag `rugged_tree_entry` to activate the Rugged method.

Part of four Rugged changes identified in
https://gitlab.com/gitlab-org/gitlab-ce/issues/57317.
parent 28883d8e
No related branches found
No related tags found
Loading
Pipeline #50743223 failed
---
title: Bring back Rugged implementation of TreeEntry
merge_request: 25706
author:
type: other
......@@ -23,6 +23,10 @@ class Blob
class << self
def find(repository, sha, path, limit: MAX_DATA_DISPLAY_SIZE)
tree_entry(repository, sha, path, limit)
end
def tree_entry(repository, sha, path, limit)
return unless path
path = path.sub(%r{\A/*}, '')
......@@ -179,3 +183,5 @@ def has_lfs_version_key?
end
end
end
Gitlab::Git::Blob.singleton_class.prepend Gitlab::Git::RuggedImpl::Blob::ClassMethods
# frozen_string_literal: true
# NOTE: This code is legacy. Do not add/modify code here unless you have
# discussed with the Gitaly team. See
# https://docs.gitlab.com/ee/development/gitaly.html#legacy-rugged-code
# for more details.
module Gitlab
module Git
module RuggedImpl
module Blob
module ClassMethods
extend ::Gitlab::Utils::Override
override :tree_entry
def tree_entry(repository, sha, path, limit)
if Feature.enabled?(:rugged_tree_entry)
rugged_tree_entry(repository, sha, path, limit)
else
super
end
end
private
def rugged_tree_entry(repository, sha, path, limit)
return unless path
# Strip any leading / characters from the path
path = path.sub(%r{\A/*}, '')
rugged_commit = repository.lookup(sha)
root_tree = rugged_commit.tree
blob_entry = find_entry_by_path(repository, root_tree.oid, *path.split('/'))
return nil unless blob_entry
if blob_entry[:type] == :commit
submodule_blob(blob_entry, path, sha)
else
blob = repository.lookup(blob_entry[:oid])
if blob
new(
id: blob.oid,
name: blob_entry[:name],
size: blob.size,
# Rugged::Blob#content is expensive; don't call it if we don't have to.
data: limit.zero? ? '' : blob.content(limit),
mode: blob_entry[:filemode].to_s(8),
path: path,
commit_id: sha,
binary: blob.binary?
)
end
end
rescue Rugged::ReferenceError
nil
end
# Recursive search of blob id by path
#
# Ex.
# blog/ # oid: 1a
# app/ # oid: 2a
# models/ # oid: 3a
# file.rb # oid: 4a
#
#
# Blob.find_entry_by_path(repo, '1a', 'blog', 'app', 'file.rb') # => '4a'
#
def find_entry_by_path(repository, root_id, *path_parts)
root_tree = repository.lookup(root_id)
entry = root_tree.find do |entry|
entry[:name] == path_parts[0]
end
return nil unless entry
if path_parts.size > 1
return nil unless entry[:type] == :tree
path_parts.shift
find_entry_by_path(repository, entry[:oid], *path_parts)
else
[:blob, :commit].include?(entry[:type]) ? entry : nil
end
end
def submodule_blob(blob_entry, path, sha)
new(
id: blob_entry[:oid],
name: blob_entry[:name],
size: 0,
data: '',
path: path,
commit_id: sha
)
end
end
end
end
end
end
......@@ -18,7 +18,7 @@
end
end
describe '.find' do
shared_examples '.find' do
context 'nil path' do
let(:blob) { Gitlab::Git::Blob.find(repository, SeedRepo::Commit::ID, nil) }
......@@ -128,6 +128,20 @@
end
end
describe '.find with Gitaly enabled' do
it_behaves_like '.find'
end
describe '.find with Rugged enabled', :enable_rugged do
it 'calls out to the Rugged implementation' do
allow_any_instance_of(Rugged).to receive(:rev_parse).with(SeedRepo::Commit::ID).and_call_original
described_class.find(repository, SeedRepo::Commit::ID, 'files/images/6049019_460s.jpg')
end
it_behaves_like '.find'
end
describe '.raw' do
let(:raw_blob) { Gitlab::Git::Blob.raw(repository, SeedRepo::RubyBlob::ID) }
let(:bad_blob) { Gitlab::Git::Blob.raw(repository, SeedRepo::BigCommit::ID) }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment