diff options
Diffstat (limited to 'app/models/merge_request_diff_file.rb')
-rw-r--r-- | app/models/merge_request_diff_file.rb | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/app/models/merge_request_diff_file.rb b/app/models/merge_request_diff_file.rb index f7648937c1d..36902e43a77 100644 --- a/app/models/merge_request_diff_file.rb +++ b/app/models/merge_request_diff_file.rb @@ -15,7 +15,12 @@ class MergeRequestDiffFile < ApplicationRecord end def utf8_diff - fetched_diff = diff + fetched_diff = if Feature.enabled?(:externally_stored_diffs_caching_export) && + merge_request_diff&.stored_externally? + diff_export + else + diff + end return '' if fetched_diff.blank? @@ -45,4 +50,40 @@ class MergeRequestDiffFile < ApplicationRecord content end end + + private + + # This method is meant to be used during Project Export. + # It is identical to the behaviour in #diff with the only + # difference of caching externally stored diffs on local disk in + # temp storage location in order to improve diff export performance. + def diff_export + content = merge_request_diff.cached_external_diff do |file| + file.seek(external_diff_offset) + + force_encode_utf8(file.read(external_diff_size)) + end + + # See #diff + if binary? + content = begin + content.unpack1('m0') + rescue ArgumentError + content + end + end + + content + rescue StandardError => e + log_payload = { + message: 'Cached external diff export failed', + merge_request_diff_file_id: id, + merge_request_diff_id: merge_request_diff&.id + } + + Gitlab::ExceptionLogFormatter.format!(e, log_payload) + Gitlab::AppLogger.warn(log_payload) + + diff + end end |