diff --git a/jh/app/models/jh/merge_request.rb b/jh/app/models/jh/merge_request.rb
index 1213aac99b2df7203b6908ad914594dd3086182d..7f3fd1da147255e22e12fa445cccfa351fa69a7d 100644
--- a/jh/app/models/jh/merge_request.rb
+++ b/jh/app/models/jh/merge_request.rb
@@ -14,5 +14,29 @@ module MergeRequest
       include ContentValidateable
       validates :title, :description, content_validation: true, if: :with_project_should_validate_content?
     end
+
+    override :mergeable_ci_state?
+    def mergeable_ci_state?
+      return super unless ::MergeRequests::MonorepoService.monorepo_enabled?(self)
+      return super if diff_head_pipeline
+
+      # The following code logic refers to the Upstream code "MergeRequest#mergeable_ci_state?"
+      return true unless only_allow_merge_if_pipeline_succeeds? ||
+        (auto_merge_strategy == ::AutoMergeService::STRATEGY_MERGE_WHEN_CHECKS_PASS && has_ci_enabled?)
+
+      return false unless mono_central_pipeline
+
+      return true if project.allow_merge_on_skipped_pipeline?(inherit_group_setting: true) &&
+        mono_central_pipeline.skipped?
+
+      mono_central_pipeline.success?
+    end
+
+    private
+
+    def mono_central_pipeline
+      monorepo_service = ::MergeRequests::MonorepoService.new(project.root_ancestor, source_branch)
+      monorepo_service.central_pipeline(filter_by_precise_time_range: false)
+    end
   end
 end
diff --git a/jh/app/services/merge_requests/monorepo_service.rb b/jh/app/services/merge_requests/monorepo_service.rb
index e267d245ce5a597ee094dfeb76a274ce9a4209fa..39c8ea545483c6d64fad11c02f71dda42014bdd6 100644
--- a/jh/app/services/merge_requests/monorepo_service.rb
+++ b/jh/app/services/merge_requests/monorepo_service.rb
@@ -127,13 +127,14 @@ def cancel_lease!
       Gitlab::ExclusiveLease.cancel(lease_key, lease_value)
     end
 
-    def central_pipeline
+    # "filter_by_precise_time_range" is used to solve the problem of circular references.
+    def central_pipeline(filter_by_precise_time_range: true)
       return if ci_central_project.nil?
 
       pipelines = ::Ci::PipelinesFinder.new(
         ci_central_project,
         @root_group.owners.allow_cross_joins_across_databases(url: "https://jihulab.com/gitlab-cn/gitlab/-/issues/4002").first,
-        central_pipeline_finder_params
+        central_pipeline_finder_params(filter_by_precise_time_range)
       ).execute
 
       pipelines.find do |pipeline|
@@ -213,10 +214,11 @@ def ci_central_project
       @ci_central_project ||= @root_group.projects.find_by_path(CI_CENTRAL_PROJECT_NAME)
     end
 
-    def central_pipeline_finder_params
+    def central_pipeline_finder_params(filter_by_precise_time_range)
       finder_params = { updated_after: merge_requests.first.created_at, ref: CI_CENTRAL_PROJECT_DEFAULT_BRANCH }
 
-      if merge_requests_list_status == :merged || merge_requests_list_status == :closed
+      if filter_by_precise_time_range &&
+          (merge_requests_list_status == :merged || merge_requests_list_status == :closed)
         finder_params[:updated_before] = merged_at
       end
 
diff --git a/jh/spec/models/jh/merge_request_spec.rb b/jh/spec/models/jh/merge_request_spec.rb
index 000502bb63078ce1b2bd20f2a752d4725ff83405..8f47b44a63955a7cfe078ae8b88146e5cc947c24 100644
--- a/jh/spec/models/jh/merge_request_spec.rb
+++ b/jh/spec/models/jh/merge_request_spec.rb
@@ -7,4 +7,54 @@
     it_behaves_like "content validation with project", :merge_request, :title
     it_behaves_like "content validation with project", :merge_request, :description
   end
+
+  describe '#mergeable_ci_state?' do
+    let(:mono_central_pipeline) { build(:ci_empty_pipeline) }
+    let(:merge_request) { build(:merge_request, source_project: project) }
+    let(:project) { build(:project, :repository, only_allow_merge_if_pipeline_succeeds: true) }
+
+    context 'when monorepo is enabled' do
+      before do
+        allow(::MergeRequests::MonorepoService).to receive(:monorepo_enabled?).and_return(true)
+      end
+
+      context 'when no diff_head_pipeline is associated' do
+        before do
+          allow_any_instance_of(::MergeRequests::MonorepoService)
+            .to receive(:central_pipeline)
+            .and_return(mono_central_pipeline)
+        end
+
+        context 'and has no mono_central_pipeline associated' do
+          let(:mono_central_pipeline) { nil }
+
+          it { expect(merge_request.mergeable_ci_state?).to be_falsey }
+        end
+
+        context 'and a failed mono_central_pipeline is associated' do
+          before do
+            mono_central_pipeline.status = 'failed'
+          end
+
+          it { expect(merge_request.mergeable_ci_state?).to be_falsey }
+        end
+
+        context 'and a successful mono_central_pipeline is associated' do
+          before do
+            mono_central_pipeline.status = 'success'
+          end
+
+          it { expect(merge_request.mergeable_ci_state?).to be_truthy }
+        end
+
+        context 'and a skipped mono_central_pipeline is associated' do
+          before do
+            mono_central_pipeline.status = 'skipped'
+          end
+
+          it { expect(merge_request.mergeable_ci_state?).to be_falsey }
+        end
+      end
+    end
+  end
 end