Class: Gitlab::GitalyClient::ConflictsService

Inherits:
Object
  • Object
show all
Includes:
EncodingHelper, WithFeatureFlagActors
Defined in:
lib/gitlab/gitaly_client/conflicts_service.rb

Constant Summary collapse

MAX_MSG_SIZE =
128.kilobytes.freeze

Constants included from EncodingHelper

EncodingHelper::BOM_UTF8, EncodingHelper::ENCODING_CONFIDENCE_THRESHOLD, EncodingHelper::ESCAPED_CHARS, EncodingHelper::UNICODE_REPLACEMENT_CHARACTER

Instance Attribute Summary

Attributes included from WithFeatureFlagActors

#repository_actor

Instance Method Summary collapse

Methods included from WithFeatureFlagActors

#gitaly_client_call, #gitaly_feature_flag_actors, #group_actor, #project_actor, #user_actor

Methods included from EncodingHelper

#binary_io, #detect_binary?, #detect_encoding, #detect_libgit2_binary?, #encode!, #encode_binary, #encode_utf8, #encode_utf8_no_detect, #encode_utf8_with_escaping!, #encode_utf8_with_replacement_character, #strip_bom, #unquote_path

Constructor Details

#initialize(repository, our_commit_oid, their_commit_oid) ⇒ ConflictsService

Returns a new instance of ConflictsService.



11
12
13
14
15
16
17
18
# File 'lib/gitlab/gitaly_client/conflicts_service.rb', line 11

def initialize(repository, our_commit_oid, their_commit_oid)
  @gitaly_repo = repository.gitaly_repository
  @repository = repository
  @our_commit_oid = our_commit_oid
  @their_commit_oid = their_commit_oid

  self.repository_actor = repository
end

Instance Method Details

#conflicts?Boolean

Returns:

  • (Boolean)


32
33
34
35
36
37
38
39
40
41
42
# File 'lib/gitlab/gitaly_client/conflicts_service.rb', line 32

def conflicts?
  skip_content = Feature.enabled?(:skip_conflict_files_in_gitaly, type: :experiment)
  list_conflict_files(skip_content: skip_content).any?
rescue GRPC::FailedPrecondition, GRPC::Unknown
  # The server raises FailedPrecondition when it encounters
  # ConflictSideMissing, which means a conflict exists but its `theirs` or
  # `ours` data is nil due to a non-existent file in one of the trees.
  #
  # GRPC::Unknown comes from Rugged::ReferenceError and Rugged::OdbError.
  true
end

#list_conflict_files(allow_tree_conflicts: false, skip_content: false) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
# File 'lib/gitlab/gitaly_client/conflicts_service.rb', line 20

def list_conflict_files(allow_tree_conflicts: false, skip_content: false)
  request = Gitaly::ListConflictFilesRequest.new(
    repository: @gitaly_repo,
    our_commit_oid: @our_commit_oid,
    their_commit_oid: @their_commit_oid,
    allow_tree_conflicts: allow_tree_conflicts,
    skip_content: skip_content
  )
  response = gitaly_client_call(@repository.storage, :conflicts_service, :list_conflict_files, request, timeout: GitalyClient.long_timeout)
  GitalyClient::ConflictFilesStitcher.new(response, @gitaly_repo)
end

#resolve_conflicts(target_repository, resolution, source_branch, target_branch) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/gitlab/gitaly_client/conflicts_service.rb', line 44

def resolve_conflicts(target_repository, resolution, source_branch, target_branch)
  reader = binary_io(resolution.files.to_json)

  req_enum = Enumerator.new do |y|
    header = resolve_conflicts_request_header(target_repository, resolution, source_branch, target_branch)
    y.yield Gitaly::ResolveConflictsRequest.new(header: header)

    until reader.eof?
      chunk = reader.read(MAX_MSG_SIZE)

      y.yield Gitaly::ResolveConflictsRequest.new(files_json: chunk)
    end
  end

  response = gitaly_client_call(@repository.storage, :conflicts_service, :resolve_conflicts, req_enum, remote_storage: target_repository.storage, timeout: GitalyClient.long_timeout)

  if response.resolution_error.present?
    raise Gitlab::Git::Conflict::Resolver::ResolutionError, response.resolution_error
  end
end