Merge branch 'sh-rugged-get-tree-entry' into 'master'
Bring back Rugged implementation of TreeEntry See merge request gitlab-org/gitlab-ce!25706
This commit is contained in:
		
						commit
						b63efb09a5
					
				|  | @ -0,0 +1,5 @@ | |||
| --- | ||||
| title: Bring back Rugged implementation of TreeEntry | ||||
| merge_request: 25706 | ||||
| author: | ||||
| type: other | ||||
|  | @ -23,6 +23,10 @@ module Gitlab | |||
| 
 | ||||
|       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 @@ module Gitlab | |||
|     end | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| Gitlab::Git::Blob.singleton_class.prepend Gitlab::Git::RuggedImpl::Blob::ClassMethods | ||||
|  |  | |||
|  | @ -0,0 +1,106 @@ | |||
| # 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 | ||||
|  | @ -18,7 +18,7 @@ describe Gitlab::Git::Blob, :seed_helper do | |||
|     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 @@ describe Gitlab::Git::Blob, :seed_helper do | |||
|     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) } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue