diff options
Diffstat (limited to 'lib/gitlab/git/rugged_impl/tree.rb')
-rw-r--r-- | lib/gitlab/git/rugged_impl/tree.rb | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/lib/gitlab/git/rugged_impl/tree.rb b/lib/gitlab/git/rugged_impl/tree.rb index 5993c8888d3..40c003821b9 100644 --- a/lib/gitlab/git/rugged_impl/tree.rb +++ b/lib/gitlab/git/rugged_impl/tree.rb @@ -13,18 +13,53 @@ module Gitlab extend ::Gitlab::Utils::Override include Gitlab::Git::RuggedImpl::UseRugged + TREE_SORT_ORDER = { tree: 0, blob: 1, commit: 2 }.freeze + override :tree_entries def tree_entries(repository, sha, path, recursive, pagination_params = nil) if use_rugged?(repository, :rugged_tree_entries) - [ - execute_rugged_call(:tree_entries_with_flat_path_from_rugged, repository, sha, path, recursive), - nil - ] + entries = execute_rugged_call(:tree_entries_with_flat_path_from_rugged, repository, sha, path, recursive) + + if pagination_params + paginated_response(entries, pagination_params[:limit], pagination_params[:page_token].to_s) + else + [entries, nil] + end else super end end + # Rugged version of TreePagination in Go: https://gitlab.com/gitlab-org/gitaly/-/merge_requests/3611 + def paginated_response(entries, limit, token) + total_entries = entries.count + + return [[], nil] if limit == 0 || limit.blank? + + entries = Gitlab::Utils.stable_sort_by(entries) { |x| TREE_SORT_ORDER[x.type] } + + if token.blank? + index = 0 + else + index = entries.index { |entry| entry.id == token } + + raise Gitlab::Git::CommandError, "could not find starting OID: #{token}" if index.nil? + + index += 1 + end + + return [entries[index..], nil] if limit < 0 + + last_index = index + limit + result = entries[index...last_index] + + if last_index < total_entries + cursor = Gitaly::PaginationCursor.new(next_cursor: result.last.id) + end + + [result, cursor] + end + def tree_entries_with_flat_path_from_rugged(repository, sha, path, recursive) tree_entries_from_rugged(repository, sha, path, recursive).tap do |entries| # This was an optimization to reduce N+1 queries for Gitaly |