blob: 7b099543c8392925b300e31bf88af4ce694114d7 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
# frozen_string_literal: true
module Gitlab
module Diff
class FileCollectionSorter
B_FOLLOWS_A = 1
A_FOLLOWS_B = -1
EQUIVALENT = 0
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 B_FOLLOWS_A if a_parts.size < b_parts.size && a_parts.empty?
return A_FOLLOWS_B if a_parts.size > b_parts.size && b_parts.empty?
comparison = a_part <=> b_part
return comparison unless comparison == EQUIVALENT
return compare_path_parts(a_parts, b_parts) if a_parts.any? && b_parts.any?
# If A and B have the same name (e.g. symlink change), they are identical so return 0
EQUIVALENT
end
end
end
end
|