Skip to content

Add "skip content" Gitaly feature to conflict checks

What does this MR do and why?

This MR adds a new experiment to skip conflict files in Gitaly when checking mergeability. This should reduce the amount of time that the MergeRequestMergeabilityCheckWorker spends in a transaction.

How to set up and validate locally

  1. Enable the skip_conflict_files_in_gitaly feature flag
  2. Run bundler and confirm Gitaly is up to date
  3. Create a merge conflict in a merge request
  4. Confirm nothing has exploded 😃

MR acceptance checklist

Related to #408142 (closed)

Diff

diff --git a/lib/gitlab/merge_requests/mergeability_check_worker.rb b/lib/gitlab/merge_requests/mergeability_check_worker.rb
index 0946005..437d11d 100644
--- a/lib/gitlab/merge_requests/mergeability_check_worker.rb
+++ b/lib/gitlab/merge_requests/mergeability_check_worker.rb
@@ -18,7 +18,7 @@ require 'gitaly/conflicts_service'
 require 'gitaly/conflict_files_stitcher'
 
 class MergeRequestMergeabilityCheckWorker
-  def initialize(repository, our_commit_oid, their_commit_oid)
+  def initialize(repository, our_commit_oid, their_commit_oid, skip_content: false)
     self.repository_actor = repository
   end
 
@@ -32,14 +32,24 @@ class MergeRequestMergeabilityCheckWorker
     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
+      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
 
-  def conflicts?
-    list_conflict_files.any?
+  def conflicts?
+    if Feature.enabled?(:skip_conflict_files_in_gitaly, type: :experiment)
+      list_conflict_files(skip_content: true).any?
+    else
+      list_conflict_files.any?
+    end
+  rescue GRPC::FailedPrecondition, GRPC::Unknown
+    # The server raises FailedPrecondition when it encounters
+    # ConflictSideMissing, which means a conflict exists but its `theirs` or
+    # `ours` side is missing.
+    #
+    # We don't want to count these as conflicts, so we return false.
+    false
   rescue GRPC::Unavailable
     # The server may be unavailable, so we don't want to count this as a
     # conflict.
     false
   end

This description was generated for revision d30e884a using AI

Edited by Gary Holtz

Merge request reports