summaryrefslogtreecommitdiff
path: root/lib/gitlab/git/rugged_impl/tree.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/git/rugged_impl/tree.rb')
-rw-r--r--lib/gitlab/git/rugged_impl/tree.rb43
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