diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-12-17 14:59:07 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-12-17 14:59:07 +0300 |
commit | 8b573c94895dc0ac0e1d9d59cf3e8745e8b539ca (patch) | |
tree | 544930fb309b30317ae9797a9683768705d664c4 /lib/gitlab/diff | |
parent | 4b1de649d0168371549608993deac953eb692019 (diff) |
Add latest changes from gitlab-org/gitlab@13-7-stable-eev13.7.0-rc42
Diffstat (limited to 'lib/gitlab/diff')
-rw-r--r-- | lib/gitlab/diff/file_collection/base.rb | 18 | ||||
-rw-r--r-- | lib/gitlab/diff/file_collection/merge_request_diff_base.rb | 8 | ||||
-rw-r--r-- | lib/gitlab/diff/file_collection/merge_request_diff_batch.rb | 21 | ||||
-rw-r--r-- | lib/gitlab/diff/file_collection_sorter.rb | 43 |
4 files changed, 80 insertions, 10 deletions
diff --git a/lib/gitlab/diff/file_collection/base.rb b/lib/gitlab/diff/file_collection/base.rb index cf0611e44da..8f4f8febec0 100644 --- a/lib/gitlab/diff/file_collection/base.rb +++ b/lib/gitlab/diff/file_collection/base.rb @@ -30,12 +30,16 @@ module Gitlab @diffs ||= diffable.raw_diffs(diff_options) end - def diff_files - raw_diff_files + def diff_files(sorted: false) + raw_diff_files(sorted: sorted) end - def raw_diff_files - @raw_diff_files ||= diffs.decorate! { |diff| decorate_diff!(diff) } + def raw_diff_files(sorted: false) + strong_memoize(:"raw_diff_files_#{sorted}") do + collection = diffs.decorate! { |diff| decorate_diff!(diff) } + collection = sort_diffs(collection) if sorted + collection + end end def diff_file_paths @@ -111,6 +115,12 @@ module Gitlab fallback_diff_refs: fallback_diff_refs, stats: stats) end + + def sort_diffs(diffs) + return diffs unless Feature.enabled?(:sort_diffs, project, default_enabled: false) + + Gitlab::Diff::FileCollectionSorter.new(diffs).sort + end end end end diff --git a/lib/gitlab/diff/file_collection/merge_request_diff_base.rb b/lib/gitlab/diff/file_collection/merge_request_diff_base.rb index 16257bb5ff5..d2ca86fdfe7 100644 --- a/lib/gitlab/diff/file_collection/merge_request_diff_base.rb +++ b/lib/gitlab/diff/file_collection/merge_request_diff_base.rb @@ -16,7 +16,7 @@ module Gitlab fallback_diff_refs: merge_request_diff.fallback_diff_refs) end - def diff_files + def diff_files(sorted: false) strong_memoize(:diff_files) do diff_files = super @@ -26,6 +26,12 @@ module Gitlab end end + def raw_diff_files(sorted: false) + # We force `sorted` to `false` as we don't need to sort the diffs when + # dealing with `MergeRequestDiff` since we sort its files on create. + super(sorted: false) + end + override :write_cache def write_cache highlight_cache.write_if_empty diff --git a/lib/gitlab/diff/file_collection/merge_request_diff_batch.rb b/lib/gitlab/diff/file_collection/merge_request_diff_batch.rb index 9af66318b89..64523f3b730 100644 --- a/lib/gitlab/diff/file_collection/merge_request_diff_batch.rb +++ b/lib/gitlab/diff/file_collection/merge_request_diff_batch.rb @@ -11,7 +11,7 @@ module Gitlab # class MergeRequestDiffBatch < MergeRequestDiffBase DEFAULT_BATCH_PAGE = 1 - DEFAULT_BATCH_SIZE = 20 + DEFAULT_BATCH_SIZE = 30 attr_reader :pagination_data @@ -21,9 +21,9 @@ module Gitlab @paginated_collection = load_paginated_collection(batch_page, batch_size, diff_options) @pagination_data = { - current_page: @paginated_collection.current_page, - next_page: @paginated_collection.next_page, - total_pages: @paginated_collection.total_pages + current_page: batch_gradual_load? ? nil : @paginated_collection.current_page, + next_page: batch_gradual_load? ? nil : @paginated_collection.next_page, + total_pages: batch_gradual_load? ? relation.size : @paginated_collection.total_pages } end @@ -62,17 +62,28 @@ module Gitlab @merge_request_diff.merge_request_diff_files end + # rubocop: disable CodeReuse/ActiveRecord def load_paginated_collection(batch_page, batch_size, diff_options) batch_page ||= DEFAULT_BATCH_PAGE batch_size ||= DEFAULT_BATCH_SIZE paths = diff_options&.fetch(:paths, nil) - paginated_collection = relation.page(batch_page).per(batch_size) + paginated_collection = if batch_gradual_load? + relation.offset(batch_page).limit([batch_size.to_i, DEFAULT_BATCH_SIZE].min) + else + relation.page(batch_page).per(batch_size) + end + paginated_collection = paginated_collection.by_paths(paths) if paths paginated_collection end + # rubocop: enable CodeReuse/ActiveRecord + + def batch_gradual_load? + Feature.enabled?(:diffs_gradual_load, @merge_request_diff.project, default_enabled: true) + end end end end diff --git a/lib/gitlab/diff/file_collection_sorter.rb b/lib/gitlab/diff/file_collection_sorter.rb new file mode 100644 index 00000000000..94626875580 --- /dev/null +++ b/lib/gitlab/diff/file_collection_sorter.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +module Gitlab + module Diff + class FileCollectionSorter + attr_reader :diffs + + def initialize(diffs) + @diffs = diffs + end + + def sort + diffs.sort do |a, b| + compare_path_parts(path_parts(a), path_parts(b)) + end + end + + private + + def path_parts(diff) + (diff.new_path.presence || diff.old_path).split(::File::SEPARATOR) + end + + # Used for sorting the file paths by: + # 1. Directory name + # 2. Depth + # 3. File name + def compare_path_parts(a_parts, b_parts) + a_part = a_parts.shift + b_part = b_parts.shift + + return 1 if a_parts.size < b_parts.size && a_parts.empty? + return -1 if a_parts.size > b_parts.size && b_parts.empty? + + comparison = a_part <=> b_part + + return comparison unless comparison == 0 + + compare_path_parts(a_parts, b_parts) + end + end + end +end |