summaryrefslogtreecommitdiff
path: root/lib/gitlab/diff/file.rb
blob: c73208329d559261d17b09ec6d576025bc8ab3d5 (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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
module Gitlab
  module Diff
    class File
      attr_reader :diff, :repository, :diff_refs

      delegate :new_file, :deleted_file, :renamed_file,
        :old_path, :new_path, :a_mode, :b_mode,
        :submodule?, :too_large?, to: :diff, prefix: false

      def initialize(diff, repository:, diff_refs: nil)
        @diff = diff
        @repository = repository
        @diff_refs = diff_refs
      end

      def line_code(line)
        return if line.meta?

        Gitlab::Diff::LineCode.generate(file_path, line.new_pos, line.old_pos)
      end

      def line_for_line_code(code)
        diff_lines.find { |line| line_code(line) == code }
      end

      def content_commit
        return unless diff_refs
        
        repository.commit(deleted_file ? old_ref : new_ref)
      end

      def old_ref
        diff_refs.try(:base_sha)
      end

      def new_ref
        diff_refs.try(:head_sha)
      end

      # Array of Gitlab::Diff::Line objects
      def diff_lines
        @lines ||= Gitlab::Diff::Parser.new.parse(raw_diff.each_line).to_a
      end

      def highlighted_diff_lines
        @highlighted_diff_lines ||= Gitlab::Diff::Highlight.new(self, repository: self.repository).highlight
      end

      def parallel_diff_lines
        @parallel_diff_lines ||= Gitlab::Diff::ParallelDiff.new(self).parallelize
      end

      def mode_changed?
        a_mode && b_mode && a_mode != b_mode
      end

      def raw_diff
        diff.diff.to_s
      end

      def next_line(index)
        diff_lines[index + 1]
      end

      def prev_line(index)
        diff_lines[index - 1] if index > 0
      end

      def file_path
        new_path.presence || old_path
      end

      def added_lines
        diff_lines.count(&:added?)
      end

      def removed_lines
        diff_lines.count(&:removed?)
      end

      def old_blob(commit = content_commit)
        return unless commit

        parent_id = commit.parent_id
        return unless parent_id

        repository.blob_at(parent_id, old_path)
      end

      def blob(commit = content_commit)
        return unless commit
        repository.blob_at(commit.id, file_path)
      end
    end
  end
end