From 9190cea21524f936c0ae8a9e754c861f13583fc5 Mon Sep 17 00:00:00 2001
From: Adam Niedzielski <adamsunday@gmail.com>
Date: Fri, 9 Dec 2016 11:12:38 +0100
Subject: [PATCH] Do not reload diff for merge request made from fork when
 target branch in fork is updated

The target branch of a merge request has to be a branch in the project
for which the merge request is submitted. When a branch changes in a fork,
it does not make sense to reload diffs of merge requests in the upstream
project that use the same branch name as the target branch.
Please note that it does make sense to reload diffs when the source branch
changes.
---
 app/models/merge_request.rb                   |  4 ++-
 .../merge_requests/refresh_service.rb         | 10 ++++---
 ...h-main-when-fork-target-branch-updated.yml |  4 +++
 .../merge_requests/refresh_service_spec.rb    | 28 +++++++++++++------
 4 files changed, 32 insertions(+), 14 deletions(-)
 create mode 100644 changelogs/unreleased/do-not-refresh-main-when-fork-target-branch-updated.yml

diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index dd9f1a7c85b..ea3cf1cdaac 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -101,7 +101,9 @@ class MergeRequest < ActiveRecord::Base
   validate :validate_branches, unless: [:allow_broken, :importing?, :closed_without_fork?]
   validate :validate_fork, unless: :closed_without_fork?
 
-  scope :by_branch, ->(branch_name) { where("(source_branch LIKE :branch) OR (target_branch LIKE :branch)", branch: branch_name) }
+  scope :by_source_or_target_branch, ->(branch_name) do
+    where("source_branch = :branch OR target_branch = :branch", branch: branch_name)
+  end
   scope :cared, ->(user) { where('assignee_id = :user OR author_id = :user', user: user.id) }
   scope :by_milestone, ->(milestone) { where(milestone_id: milestone) }
   scope :of_projects, ->(ids) { where(target_project_id: ids) }
diff --git a/app/services/merge_requests/refresh_service.rb b/app/services/merge_requests/refresh_service.rb
index e4056306bc4..0a9563ed7e7 100644
--- a/app/services/merge_requests/refresh_service.rb
+++ b/app/services/merge_requests/refresh_service.rb
@@ -55,8 +55,9 @@ module MergeRequests
     # Refresh merge request diff if we push to source or target branch of merge request
     # Note: we should update merge requests from forks too
     def reload_merge_requests
-      merge_requests = @project.merge_requests.opened.by_branch(@branch_name).to_a
-      merge_requests += fork_merge_requests.by_branch(@branch_name).to_a
+      merge_requests = @project.merge_requests.opened.
+        by_source_or_target_branch(@branch_name).to_a
+      merge_requests += fork_merge_requests
       merge_requests = filter_merge_requests(merge_requests)
 
       merge_requests.each do |merge_request|
@@ -157,13 +158,14 @@ module MergeRequests
     def merge_requests_for_source_branch
       @source_merge_requests ||= begin
         merge_requests = @project.origin_merge_requests.opened.where(source_branch: @branch_name).to_a
-        merge_requests += fork_merge_requests.where(source_branch: @branch_name).to_a
+        merge_requests += fork_merge_requests
         filter_merge_requests(merge_requests)
       end
     end
 
     def fork_merge_requests
-      @fork_merge_requests ||= @project.fork_merge_requests.opened
+      @fork_merge_requests ||= @project.fork_merge_requests.opened.
+        where(source_branch: @branch_name).to_a
     end
 
     def branch_added?
diff --git a/changelogs/unreleased/do-not-refresh-main-when-fork-target-branch-updated.yml b/changelogs/unreleased/do-not-refresh-main-when-fork-target-branch-updated.yml
new file mode 100644
index 00000000000..12b1460f388
--- /dev/null
+++ b/changelogs/unreleased/do-not-refresh-main-when-fork-target-branch-updated.yml
@@ -0,0 +1,4 @@
+---
+title: Do not reload diff for merge request made from fork when target branch in fork is updated
+merge_request: 7973
+author:
diff --git a/spec/services/merge_requests/refresh_service_spec.rb b/spec/services/merge_requests/refresh_service_spec.rb
index bc340ff9d3c..7e3705983fb 100644
--- a/spec/services/merge_requests/refresh_service_spec.rb
+++ b/spec/services/merge_requests/refresh_service_spec.rb
@@ -126,17 +126,27 @@ describe MergeRequests::RefreshService, services: true do
     end
 
     context 'push to fork repo target branch' do
-      before do
-        service.new(@fork_project, @user).execute(@oldrev, @newrev, 'refs/heads/feature')
-        reload_mrs
+      describe 'changes to merge requests' do
+        before do
+          service.new(@fork_project, @user).execute(@oldrev, @newrev, 'refs/heads/feature')
+          reload_mrs
+        end
+
+        it { expect(@merge_request.notes).to be_empty }
+        it { expect(@merge_request).to be_open }
+        it { expect(@fork_merge_request.notes).to be_empty }
+        it { expect(@fork_merge_request).to be_open }
+        it { expect(@build_failed_todo).to be_pending }
+        it { expect(@fork_build_failed_todo).to be_pending }
       end
 
-      it { expect(@merge_request.notes).to be_empty }
-      it { expect(@merge_request).to be_open }
-      it { expect(@fork_merge_request.notes).to be_empty }
-      it { expect(@fork_merge_request).to be_open }
-      it { expect(@build_failed_todo).to be_pending }
-      it { expect(@fork_build_failed_todo).to be_pending }
+      describe 'merge request diff' do
+        it 'does not reload the diff of the merge request made from fork' do
+          expect do
+            service.new(@fork_project, @user).execute(@oldrev, @newrev, 'refs/heads/feature')
+          end.not_to change { @fork_merge_request.reload.merge_request_diff }
+        end
+      end
     end
 
     context 'push to origin repo target branch after fork project was removed' do
-- 
GitLab