Class: Gitlab::Git::Conflict::File

Inherits:
Object
  • Object
show all
Defined in:
lib/gitlab/git/conflict/file.rb

Constant Summary collapse

UnsupportedEncoding =
Class.new(StandardError)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(repository, commit_oid, conflict, raw_content) ⇒ File

Returns a new instance of File.



13
14
15
16
17
18
19
20
21
# File 'lib/gitlab/git/conflict/file.rb', line 13

def initialize(repository, commit_oid, conflict, raw_content)
  @repository = repository
  @commit_oid = commit_oid
  @ancestor_path = conflict[:ancestor][:path]
  @their_path = conflict[:theirs][:path]
  @our_path = conflict[:ours][:path]
  @our_mode = conflict[:ours][:mode]
  @raw_content = raw_content
end

Instance Attribute Details

#ancestor_pathObject (readonly)

Returns the value of attribute ancestor_path.



9
10
11
# File 'lib/gitlab/git/conflict/file.rb', line 9

def ancestor_path
  @ancestor_path
end

#commit_oidObject (readonly)

Returns the value of attribute commit_oid.



9
10
11
# File 'lib/gitlab/git/conflict/file.rb', line 9

def commit_oid
  @commit_oid
end

#our_modeObject (readonly)

Returns the value of attribute our_mode.



9
10
11
# File 'lib/gitlab/git/conflict/file.rb', line 9

def our_mode
  @our_mode
end

#our_pathObject (readonly)

Returns the value of attribute our_path.



9
10
11
# File 'lib/gitlab/git/conflict/file.rb', line 9

def our_path
  @our_path
end

#raw_contentObject

Returns the value of attribute raw_content.



11
12
13
# File 'lib/gitlab/git/conflict/file.rb', line 11

def raw_content
  @raw_content
end

#repositoryObject (readonly)

Returns the value of attribute repository.



9
10
11
# File 'lib/gitlab/git/conflict/file.rb', line 9

def repository
  @repository
end

#their_pathObject (readonly)

Returns the value of attribute their_path.



9
10
11
# File 'lib/gitlab/git/conflict/file.rb', line 9

def their_path
  @their_path
end

Instance Method Details

#contentObject



37
38
39
40
41
42
43
# File 'lib/gitlab/git/conflict/file.rb', line 37

def content
  @content ||= @raw_content.dup.force_encoding('UTF-8')

  raise UnsupportedEncoding unless @content.valid_encoding?

  @content
end

#line_code(line) ⇒ Object



63
64
65
# File 'lib/gitlab/git/conflict/file.rb', line 63

def line_code(line)
  Gitlab::Git.diff_line_code(our_path, line[:line_new], line[:line_old])
end

#linesObject



23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/gitlab/git/conflict/file.rb', line 23

def lines
  return @lines if defined?(@lines)

  begin
    @type = 'text'
    @lines = Gitlab::Git::Conflict::Parser.parse(content,
                                                 our_path: our_path,
                                                 their_path: their_path)
  rescue Gitlab::Git::Conflict::Parser::ParserError
    @type = 'text-editor'
    @lines = nil
  end
end

#our_blobObject



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/gitlab/git/conflict/file.rb', line 51

def our_blob
  # REFACTOR NOTE: the source of `commit_oid` used to be
  # `merge_request.diff_refs.head_sha`. Instead of passing this value
  # around the new lib structure, I decided to use `@commit_oid` which is
  # equivalent to `merge_request.source_branch_head.raw.rugged_commit.oid`.
  # That is what `merge_request.diff_refs.head_sha` is equivalent to when
  # `merge_request` is not persisted (see `MergeRequest#diff_head_commit`).
  # I think using the same oid is more consistent anyways, but if Conflicts
  # start breaking, the change described above is a good place to look at.
  @our_blob ||= repository.blob_at(@commit_oid, our_path)
end

#pathObject



99
100
101
102
103
104
105
106
# File 'lib/gitlab/git/conflict/file.rb', line 99

def path
  # There are conflict scenarios (e.g. file is removed on source) wherein
  # our_path will be blank/nil. Since we are indexing them by path in
  # `#conflicts` helper and we want to match the diff file to a conflict
  # in `DiffFileEntity#highlighted_diff_lines`, we need to fallback to
  # their_path (this is the path on target).
  our_path.presence || their_path
end

#resolve_content(resolution) ⇒ Object



91
92
93
94
95
96
97
# File 'lib/gitlab/git/conflict/file.rb', line 91

def resolve_content(resolution)
  if resolution == content
    raise Gitlab::Git::Conflict::Resolver::ResolutionError, "Resolved content has no changes for file #{our_path}"
  end

  resolution
end

#resolve_lines(resolution) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/gitlab/git/conflict/file.rb', line 67

def resolve_lines(resolution)
  section_id = nil

  lines.map do |line|
    unless line[:type]
      section_id = nil
      next line
    end

    section_id ||= line_code(line)

    case resolution[section_id]
    when 'head'
      next unless line[:type] == 'new'
    when 'origin'
      next unless line[:type] == 'old'
    else
      raise Gitlab::Git::Conflict::Resolver::ResolutionError, "Missing resolution for section ID: #{section_id}"
    end

    line
  end.compact
end

#typeObject



45
46
47
48
49
# File 'lib/gitlab/git/conflict/file.rb', line 45

def type
  lines unless @type

  @type.inquiry
end