Commit 94076566 authored by charlie ablett's avatar charlie ablett

Merge branch '35824-Indicate-Reverted-MRs-in-MR-Header' into 'master'

Indicate reverted status of a merged merge request

See merge request gitlab-org/gitlab!45471
parents 0d29d658 28b3db68
...@@ -428,6 +428,10 @@ class Commit ...@@ -428,6 +428,10 @@ class Commit
end end
def has_been_reverted?(current_user, notes_association = nil) def has_been_reverted?(current_user, notes_association = nil)
reverting_commit(current_user, notes_association).present?
end
def reverting_commit(current_user, notes_association = nil)
ext = Gitlab::ReferenceExtractor.new(project, current_user) ext = Gitlab::ReferenceExtractor.new(project, current_user)
notes_association ||= notes_with_associations notes_association ||= notes_with_associations
...@@ -435,7 +439,7 @@ class Commit ...@@ -435,7 +439,7 @@ class Commit
note.all_references(current_user, extractor: ext) note.all_references(current_user, extractor: ext)
end end
ext.commits.any? { |commit_ref| commit_ref.reverts_commit?(self, current_user) } ext.commits.find { |commit_ref| commit_ref.reverts_commit?(self, current_user) }
end end
def change_type_title(user) def change_type_title(user)
......
...@@ -1576,6 +1576,26 @@ class MergeRequest < ApplicationRecord ...@@ -1576,6 +1576,26 @@ class MergeRequest < ApplicationRecord
!merge_commit.has_been_reverted?(current_user, notes_association) !merge_commit.has_been_reverted?(current_user, notes_association)
end end
def reverted_by_merge_request?(current_user)
reverting_merge_request(current_user).present?
end
def reverting_merge_request(current_user)
return unless merge_commit
return unless merged_at
reverting_commit = merge_commit.reverting_commit(current_user, notes_with_associations)
if reverting_commit
MergeRequestsFinder.new(
current_user,
project_id: project.id,
commit_sha: reverting_commit.sha,
state: 'merged'
).execute.first
end
end
def merged_at def merged_at
strong_memoize(:merged_at) do strong_memoize(:merged_at) do
next unless merged? next unless merged?
......
...@@ -40,11 +40,12 @@ ...@@ -40,11 +40,12 @@
.issuable-meta .issuable-meta
%ul.controls.d-flex.align-items-end %ul.controls.d-flex.align-items-end
- if merge_request.merged? %li.issuable-status.d-none.d-sm-inline-block
%li.issuable-status.d-none.d-sm-inline-block - if merge_request.reverted_by_merge_request?(current_user)
= _('MERGED (REVERTED)')
- elsif merge_request.merged?
= _('MERGED') = _('MERGED')
- elsif merge_request.closed? - elsif merge_request.closed?
%li.issuable-status.d-none.d-sm-inline-block
= sprite_icon('cancel', css_class: 'gl-vertical-align-text-bottom') = sprite_icon('cancel', css_class: 'gl-vertical-align-text-bottom')
= _('CLOSED') = _('CLOSED')
= render 'shared/merge_request_pipeline_status', merge_request: merge_request = render 'shared/merge_request_pipeline_status', merge_request: merge_request
......
...@@ -15,7 +15,10 @@ ...@@ -15,7 +15,10 @@
.issuable-status-box.status-box{ class: status_box_class(@merge_request) } .issuable-status-box.status-box{ class: status_box_class(@merge_request) }
= sprite_icon(state_icon_name, css_class: 'd-block d-sm-none') = sprite_icon(state_icon_name, css_class: 'd-block d-sm-none')
%span.d-none.d-sm-block %span.d-none.d-sm-block
= state_human_name - if @merge_request.reverted_by_merge_request?(current_user)
= _('Merged (%{reverted})').html_safe % { reverted: link_to(s_('MergeRequest|reverted'), merge_request_path(@merge_request.reverting_merge_request(current_user)), class: 'gl-reset-color! gl-text-decoration-underline') }
- else
= state_human_name
.issuable-meta .issuable-meta
#js-issuable-header-warnings #js-issuable-header-warnings
......
---
title: Indicate reverted status of a merged merge request
merge_request: 45471
author: Kev @KevSlashNull
type: added
...@@ -59,6 +59,10 @@ mainline: ...@@ -59,6 +59,10 @@ mainline:
git revert -m 2 7a39eb0 git revert -m 2 7a39eb0
``` ```
From [GitLab 13.7 onwards](https://gitlab.com/gitlab-org/gitlab/-/issues/35824), merge requests
reverted by another merge request through one of the methods described in this document
will display a link to the reverted merge request at the top-left corner within the **Merged** badge.
<!-- ## Troubleshooting <!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues Include any troubleshooting steps that you can foresee. If you know beforehand what issues
......
...@@ -16726,6 +16726,9 @@ msgstr "" ...@@ -16726,6 +16726,9 @@ msgstr ""
msgid "MERGED" msgid "MERGED"
msgstr "" msgstr ""
msgid "MERGED (REVERTED)"
msgstr ""
msgid "MR widget|Back to the Merge request" msgid "MR widget|Back to the Merge request"
msgstr "" msgstr ""
...@@ -17488,9 +17491,15 @@ msgstr "" ...@@ -17488,9 +17491,15 @@ msgstr ""
msgid "MergeRequest|Search files (%{modifier_key}P)" msgid "MergeRequest|Search files (%{modifier_key}P)"
msgstr "" msgstr ""
msgid "MergeRequest|reverted"
msgstr ""
msgid "Merged" msgid "Merged"
msgstr "" msgstr ""
msgid "Merged (%{reverted})"
msgstr ""
msgid "Merged MRs" msgid "Merged MRs"
msgstr "" msgstr ""
......
...@@ -750,6 +750,27 @@ eos ...@@ -750,6 +750,27 @@ eos
end end
end end
describe '#reverting_commit' do
let(:user) { create(:user) }
let(:issue) { create(:issue, author: user, project: project) }
it 'returns the reverting commit' do
create(:note_on_issue,
noteable: issue,
system: true,
note: commit.revert_description(user),
project: issue.project)
expect_next_instance_of(Commit) do |revert_commit|
expect(revert_commit).to receive(:reverts_commit?)
.with(commit, user)
.and_return(true)
end
expect(commit.reverting_commit(user, issue.notes_with_associations)).to eq(commit)
end
end
describe '#has_been_reverted?' do describe '#has_been_reverted?' do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:issue) { create(:issue, author: user, project: project) } let(:issue) { create(:issue, author: user, project: project) }
......
...@@ -2413,6 +2413,85 @@ RSpec.describe MergeRequest, factory_default: :keep do ...@@ -2413,6 +2413,85 @@ RSpec.describe MergeRequest, factory_default: :keep do
end end
end end
describe '#reverting_merge_request' do
subject { create(:merge_request, source_project: create(:project, :repository)) }
context 'when there is no merge_commit for the MR' do
before do
subject.metrics.update!(merged_at: Time.current.utc)
end
it 'returns nil' do
expect(subject.reverting_merge_request(nil)).to be_nil
end
end
context 'when the MR has been merged' do
before do
MergeRequests::MergeService
.new(subject.target_project, subject.author, { sha: subject.diff_head_sha })
.execute(subject)
end
context 'when there is no revert commit' do
it 'returns nil' do
expect(subject.reverting_merge_request(nil)).to be_nil
end
end
context 'when there is no merged_at for the MR' do
before do
subject.metrics.update!(merged_at: nil)
end
it 'returns nil' do
expect(subject.reverting_merge_request(nil)).to be_nil
end
end
context 'when there is a revert commit by MR' do
let(:current_user) { subject.author }
let(:branch) { subject.source_branch }
let(:project) { subject.source_project }
let(:revert_commit_id) do
params = {
commit: subject.merge_commit,
branch_name: branch,
start_branch: branch
}
Commits::RevertService.new(project, current_user, params).execute[:result]
end
let(:revert_merge_request) do
create(
:merge_request,
author: subject.author,
target_project: subject.target_project,
source_project: subject.source_project,
merge_commit_sha: revert_commit_id,
description: "This reverts merge request !#{subject.id}")
end
it 'returns the reverting merge request' do
ProcessCommitWorker.new.perform(project.id,
current_user.id,
project.commit(revert_commit_id).to_hash,
project.default_branch == branch)
MergeRequests::MergeService.new(
subject.target_project,
subject.author,
{ sha: revert_merge_request.diff_head_sha }
).execute(revert_merge_request)
expect(subject.reverting_merge_request(current_user)).to eq(revert_merge_request)
end
end
end
end
describe '#can_be_reverted?' do describe '#can_be_reverted?' do
subject { create(:merge_request, source_project: create(:project, :repository)) } subject { create(:merge_request, source_project: create(:project, :repository)) }
......
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