diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.js index e745de89b8ddeced22f71a60ae9dc1369c7b1fa5..dc252f8a9b718ec4d5c35f06d17c553aea6c0740 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.js @@ -15,7 +15,7 @@ export default { showDisabledButton />
Fast-forward merge is not possible. To merge this request, first rebase locally. diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js index 03969e33e97f0ff67e3472b6f2a8f6bf2d516d5b..8255fd3e792b140632443cf1bd91a61716226083 100644 --- a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js +++ b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js @@ -58,6 +58,7 @@ export default class MergeRequestStore { this.mergeWhenPipelineSucceeds = data.merge_when_pipeline_succeeds || false; this.mergePath = data.merge_path; this.ffOnlyEnabled = data.ff_only_enabled; + this.shouldBeRebased = !!data.should_be_rebased; this.statusPath = data.status_path; this.emailPatchesPath = data.email_patches_path; this.plainDiffPath = data.plain_diff_path; diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 8d9a30397a9581b27812f5bc3a05cd832260a115..e85b83daf9e05c66fffd3824d542f31f6edcfe71 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -524,6 +524,14 @@ class MergeRequest < ActiveRecord::Base true end + def ff_merge_possible? + project.repository.ancestor?(target_branch_sha, diff_head_sha) + end + + def should_be_rebased? + project.ff_merge_must_be_possible? && !ff_merge_possible? + end + def can_cancel_merge_when_pipeline_succeeds?(current_user) can_be_merged_by?(current_user) || self.author == current_user end diff --git a/app/serializers/merge_request_entity.rb b/app/serializers/merge_request_entity.rb index 5f2700df692eb3dd71e45c1ce41f6d5371d71166..7d3c752b8e6ee84ccffa522d34ae50f182bba2ef 100644 --- a/app/serializers/merge_request_entity.rb +++ b/app/serializers/merge_request_entity.rb @@ -13,6 +13,7 @@ class MergeRequestEntity < IssuableEntity expose :target_branch expose :target_project_id + expose :should_be_rebased?, as: :should_be_rebased expose :ff_only_enabled do |merge_request| merge_request.project.merge_requests_ff_only_enabled end diff --git a/app/views/projects/_merge_request_rebase_settings.html.haml b/app/views/projects/_merge_request_rebase_settings.html.haml new file mode 100644 index 0000000000000000000000000000000000000000..c52e09573a635dc27345ccaff42bbfa86fd93eb2 --- /dev/null +++ b/app/views/projects/_merge_request_rebase_settings.html.haml @@ -0,0 +1,13 @@ +- form = local_assigns.fetch(:form) + +.radio + = label_tag :project_merge_method_rebase_merge do + = form.radio_button :merge_method, :rebase_merge, class: "js-merge-method-radio" + %strong Merge commit with semi-linear history + %br + %span.descr + A merge commit is created for every merge, but merging is only allowed if fast-forward merge is possible. + This way you could make sure that if this merge request would build, after merging to target branch it would also build. + %br + %span.descr + When fast-forward merge is not possible, the user must first rebase locally. diff --git a/app/views/projects/_merge_request_settings.html.haml b/app/views/projects/_merge_request_settings.html.haml index 939750ed1e5ba2cb4c1acb6e48d4fcfc348f3e00..fd0c419cdacd64c6ff96f6836fc191191e467e73 100644 --- a/app/views/projects/_merge_request_settings.html.haml +++ b/app/views/projects/_merge_request_settings.html.haml @@ -11,6 +11,8 @@ %span.descr A merge commit is created for every merge, and merging is allowed as long as there are no conflicts. + = render 'merge_request_rebase_settings', form: form + = render 'merge_request_fast_forward_settings', project: @project, form: form = render 'projects/merge_request_merge_settings', form: form diff --git a/spec/features/projects/project_settings_spec.rb b/spec/features/projects/project_settings_spec.rb index 8dc94b3d5490c723f93f92bd6f10e7070efe53b4..06568817757850d3429a6440b3d4c52f0bd007b4 100644 --- a/spec/features/projects/project_settings_spec.rb +++ b/spec/features/projects/project_settings_spec.rb @@ -41,6 +41,14 @@ describe 'Edit Project Settings' do end end + it 'shows "Merge commit with semi-linear history " strategy' do + visit edit_project_path(project) + + page.within '.merge-requests-feature' do + expect(page).to have_content 'Merge commit with semi-linear history' + end + end + it 'shows "Fast-forward merge" strategy' do visit edit_project_path(project) diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js index cc3d638dd061e6004c590adf098ea4fd85ef7097..5d4c7ec09dc913a90f11b02b6a56706e3b51f19a 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js @@ -81,13 +81,13 @@ describe('MRWidgetConflicts', () => { }); }); - describe('when fast-forward merge enabled', () => { + describe('when fast-forward or semi-linear merge enabled', () => { let vm; beforeEach(() => { vm = mountComponent(ConflictsComponent, { mr: { - ffOnlyEnabled: true, + shouldBeRebased: true, }, }); });