Module: Gitlab::Import::MergeRequestHelpers

Includes:
DatabaseHelpers
Included in:
GithubImport::Importer::PullRequestImporter, MergeRequestCreator
Defined in:
lib/gitlab/import/merge_request_helpers.rb

Instance Method Summary collapse

Methods included from DatabaseHelpers

#insert_and_return_id

Instance Method Details

#create_merge_request_without_hooks(project, attributes, iid) ⇒ Object

rubocop: disable CodeReuse/ActiveRecord



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
# File 'lib/gitlab/import/merge_request_helpers.rb', line 9

def create_merge_request_without_hooks(project, attributes, iid)
  # This work must be wrapped in a transaction as otherwise we can leave
  # behind incomplete data in the event of an error. This can then lead
  # to duplicate key errors when jobs are retried.
  MergeRequest.transaction do
    # When creating merge requests there are a lot of hooks that may
    # run, for many different reasons. Many of these hooks (e.g. the
    # ones used for rendering Markdown) are completely unnecessary and
    # may even lead to transaction timeouts.
    #
    # To ensure importing pull requests has a minimal impact and can
    # complete in a reasonable time we bypass all the hooks by inserting
    # the row and then retrieving it. We then only perform the
    # additional work that is strictly necessary.
    merge_request_id = insert_and_return_id(attributes, project.merge_requests)

    merge_request = project.merge_requests.reset.find(merge_request_id)

    [merge_request, false]
  end
rescue ActiveRecord::InvalidForeignKey
  # It's possible the project has been deleted since scheduling this
  # job. In this case we'll just skip creating the merge request.
  []
rescue ActiveRecord::RecordNotUnique
  # It's possible we previously created the MR, but failed when updating
  # the Git data. In this case we'll just continue working on the
  # existing row.
  [project.merge_requests.find_by(iid: iid), true]
end

#insert_merge_request_reviewers(merge_request, reviewers) ⇒ Object



66
67
68
69
70
71
# File 'lib/gitlab/import/merge_request_helpers.rb', line 66

def insert_merge_request_reviewers(merge_request, reviewers)
  return unless reviewers.present?

  rows = reviewers.map { |reviewer_id| { merge_request_id: merge_request.id, user_id: reviewer_id } }
  MergeRequestReviewer.insert_all(rows)
end

#insert_or_replace_git_data(merge_request, source_branch_sha, target_branch_sha, already_exists = false) ⇒ Object

rubocop: enable CodeReuse/ActiveRecord



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/gitlab/import/merge_request_helpers.rb', line 41

def insert_or_replace_git_data(merge_request, source_branch_sha, target_branch_sha, already_exists = false)
  # These fields are set so we can create the correct merge request
  # diffs.
  merge_request.source_branch_sha = source_branch_sha
  merge_request.target_branch_sha = target_branch_sha

  merge_request.keep_around_commit

  # We force to recreate all diffs to replace all existing data
  # We use `.all` as otherwise `dependent: :nullify` (the default)
  # takes an effect
  merge_request.merge_request_diffs.all.delete_all if already_exists

  # MR diffs normally use an "after_save" hook to pull data from Git.
  # All of this happens in the transaction started by calling
  # create/save/etc. This in turn can lead to these transactions being
  # held open for much longer than necessary. To work around this we
  # first save the diff, then populate it.
  diff = merge_request.merge_request_diffs.build
  diff.importing = true
  diff.save
  diff.save_git_content
  diff.set_as_latest_diff
end