Commit 11fd2f80 authored by Stan Hu's avatar Stan Hu

Don't delete a branch involved in an open merge request in "Delete all merged branches" service

Customers were surprised by the previous behavior, which destroyed branches
even though an open merge request existed for it.

Closes #29427
parent a9da3743
...@@ -8,9 +8,20 @@ class DeleteMergedBranchesService < BaseService ...@@ -8,9 +8,20 @@ class DeleteMergedBranchesService < BaseService
branches = project.repository.branch_names branches = project.repository.branch_names
branches = branches.select { |branch| project.repository.merged_to_root_ref?(branch) } branches = branches.select { |branch| project.repository.merged_to_root_ref?(branch) }
# Prevent deletion of branches relevant to open merge requests
branches -= merge_request_branch_names
branches.each do |branch| branches.each do |branch|
DeleteBranchService.new(project, current_user).execute(branch) DeleteBranchService.new(project, current_user).execute(branch)
end end
end end
private
def merge_request_branch_names
# reorder(nil) is necessary for SELECT DISTINCT because default scope adds an ORDER BY
source_names = project.origin_merge_requests.opened.reorder(nil).uniq.pluck(:source_branch)
target_names = project.merge_requests.opened.reorder(nil).uniq.pluck(:target_branch)
(source_names + target_names).uniq
end
end end
---
title: Don't delete a branch involved in an open merge request in "Delete all merged
branches" service
merge_request:
author:
...@@ -40,6 +40,10 @@ FactoryGirl.define do ...@@ -40,6 +40,10 @@ FactoryGirl.define do
state :closed state :closed
end end
trait :opened do
state :opened
end
trait :reopened do trait :reopened do
state :reopened state :reopened
end end
......
...@@ -42,6 +42,19 @@ describe DeleteMergedBranchesService, services: true do ...@@ -42,6 +42,19 @@ describe DeleteMergedBranchesService, services: true do
expect { described_class.new(project, user).execute }.to raise_error(Gitlab::Access::AccessDeniedError) expect { described_class.new(project, user).execute }.to raise_error(Gitlab::Access::AccessDeniedError)
end end
end end
context 'open merge requests' do
it 'does not delete branches from open merge requests' do
fork_link = create(:forked_project_link, forked_from_project: project)
create(:merge_request, :reopened, source_project: project, target_project: project, source_branch: 'branch-merged', target_branch: 'master')
create(:merge_request, :opened, source_project: fork_link.forked_to_project, target_project: project, target_branch: 'improve/awesome', source_branch: 'master')
service.execute
expect(project.repository.branch_names).to include('branch-merged')
expect(project.repository.branch_names).to include('improve/awesome')
end
end
end end
context '#async_execute' do context '#async_execute' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment