106 lines
3 KiB
Ruby
106 lines
3 KiB
Ruby
# 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 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 unless entry
|
|
|
|
if path_parts.size > 1
|
|
return 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
|