Commit 201b0bb7 authored by Douwe Maan's avatar Douwe Maan

Refactor ff merge and get it to work with Merge when build succeeds

parent 9292d8e6
...@@ -23,7 +23,7 @@ class @MergeRequestWidget ...@@ -23,7 +23,7 @@ class @MergeRequestWidget
$('.mr-widget-body').html("<h4>" + data.merge_error + "</h4>") $('.mr-widget-body').html("<h4>" + data.merge_error + "</h4>")
else else
callback = -> merge_request_widget.mergeInProgress(deleteSourceBranch) callback = -> merge_request_widget.mergeInProgress(deleteSourceBranch)
setTimeout(callback, 2000) setTimeout(callback, 1000)
dataType: 'json' dataType: 'json'
rebaseInProgress: -> rebaseInProgress: ->
...@@ -31,9 +31,8 @@ class @MergeRequestWidget ...@@ -31,9 +31,8 @@ class @MergeRequestWidget
type: 'GET' type: 'GET'
url: $('.merge-request').data('url') url: $('.merge-request').data('url')
success: (data) => success: (data) =>
debugger
if data["rebase_in_progress?"] if data["rebase_in_progress?"]
setTimeout(merge_request_widget.rebaseInProgress, 2000) setTimeout(merge_request_widget.rebaseInProgress, 1000)
else else
location.reload() location.reload()
dataType: 'json' dataType: 'json'
......
...@@ -2,7 +2,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController ...@@ -2,7 +2,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
before_action :module_enabled before_action :module_enabled
before_action :merge_request, only: [ before_action :merge_request, only: [
:edit, :update, :show, :diffs, :commits, :builds, :merge, :merge_check, :edit, :update, :show, :diffs, :commits, :builds, :merge, :merge_check,
:ci_status, :toggle_subscription, :approve, :ff_merge, :rebase, :cancel_merge_when_build_succeeds :ci_status, :toggle_subscription, :approve, :rebase, :cancel_merge_when_build_succeeds
] ]
before_action :closes_issues, only: [:edit, :update, :show, :diffs, :commits, :builds] before_action :closes_issues, only: [:edit, :update, :show, :diffs, :commits, :builds]
before_action :validates_merge_request, only: [:show, :diffs, :commits, :builds] before_action :validates_merge_request, only: [:show, :diffs, :commits, :builds]
...@@ -179,6 +179,11 @@ class Projects::MergeRequestsController < Projects::ApplicationController ...@@ -179,6 +179,11 @@ class Projects::MergeRequestsController < Projects::ApplicationController
return return
end end
if params[:ff].present? && !@merge_request.ff_merge_possible?
@status = :failed
return
end
@merge_request.update(merge_error: nil) @merge_request.update(merge_error: nil)
if params[:merge_when_build_succeeds].present? && @merge_request.ci_commit && @merge_request.ci_commit.active? if params[:merge_when_build_succeeds].present? && @merge_request.ci_commit && @merge_request.ci_commit.active?
...@@ -191,6 +196,13 @@ class Projects::MergeRequestsController < Projects::ApplicationController ...@@ -191,6 +196,13 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end end
end end
def rebase
return access_denied! unless @merge_request.can_be_merged_by?(current_user)
return render_404 unless @merge_request.approved?
RebaseWorker.perform_async(@merge_request.id, current_user.id)
end
def branch_from def branch_from
#This is always source #This is always source
@source_project = @merge_request.nil? ? @project : @merge_request.source_project @source_project = @merge_request.nil? ? @project : @merge_request.source_project
...@@ -248,26 +260,6 @@ class Projects::MergeRequestsController < Projects::ApplicationController ...@@ -248,26 +260,6 @@ class Projects::MergeRequestsController < Projects::ApplicationController
redirect_to merge_request_path(@merge_request) redirect_to merge_request_path(@merge_request)
end end
def ff_merge
return access_denied! unless @merge_request.can_be_merged_by?(current_user)
return render_404 unless @merge_request.approved?
if @merge_request.ff_merge_possible?
MergeRequests::FfMergeService.new(merge_request.target_project, current_user).
execute(merge_request)
@status = true
else
@status = false
end
end
def rebase
return access_denied! unless @merge_request.can_be_merged_by?(current_user)
return render_404 unless @merge_request.approved?
RebaseWorker.perform_async(@merge_request.id, current_user.id)
end
protected protected
def selected_target_project def selected_target_project
...@@ -363,7 +355,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController ...@@ -363,7 +355,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end end
def merge_params def merge_params
params.permit(:should_remove_source_branch, :commit_message) params.permit(:should_remove_source_branch, :commit_message, :ff)
end end
# Make sure merge requests created before 8.0 # Make sure merge requests created before 8.0
......
...@@ -14,14 +14,4 @@ module BranchesHelper ...@@ -14,14 +14,4 @@ module BranchesHelper
::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(branch_name) ::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(branch_name)
end end
def can_rebase?(project, branch_name)
if project.protected_branch? branch_name
can?(current_user, :push_code_to_protected_branches, project)
elsif can?(current_user, :push_code, project)
true
else
false
end
end
end end
module MergeRequests module MergeRequests
# MergeService class # MergeService class
# #
# Do git merge and in case of success # Do git fast-forward merge and in case of success
# mark merge request as merged and execute all hooks and notifications # mark merge request as merged and execute all hooks and notifications
# Executed when you do merge via GitLab UI # Executed when you do fast-forward merge via GitLab UI
# #
class FfMergeService < MergeRequests::BaseService class FfMergeService < MergeRequests::MergeService
attr_reader :merge_request
def execute(merge_request)
@merge_request = merge_request
unless @merge_request.ff_merge_possible?
return error('Merge request is not mergeable')
end
merge_request.in_locked_state do
if update_head
after_merge
success
else
error('Can not merge changes')
end
end
end
private private
def update_head def commit
repository.ff_merge(current_user, merge_request.source_sha, merge_request.target_branch) return false unless @merge_request.ff_merge_possible?
end
def after_merge repository.ff_merge(current_user, merge_request.source_sha, merge_request.target_branch)
MergeRequests::PostMergeService.new(project, current_user).execute(merge_request)
end end
end end
end end
...@@ -9,6 +9,13 @@ module MergeRequests ...@@ -9,6 +9,13 @@ module MergeRequests
attr_reader :merge_request attr_reader :merge_request
def execute(merge_request) def execute(merge_request)
# Delete the ff param so we don't get into an infinite loop if it's present,
# since FfMergeService inherits from MergeService.
if params.delete(:ff).present?
FfMergeService.new(project, current_user, params).execute(merge_request)
return
end
@merge_request = merge_request @merge_request = merge_request
return error('Merge request is not mergeable') unless @merge_request.mergeable? return error('Merge request is not mergeable') unless @merge_request.mergeable?
......
- if @status
:plain
location.reload()
- else
:plain
$('.mr-widget-body').html("#{escape_javascript(render('projects/merge_requests/widget/open/reload'))}");
:plain :plain
$('.mr-widget-body').html("#{escape_javascript(render('projects/merge_requests/widget/open/ff_accept'))}") $('.mr-widget-body').html("#{escape_javascript(render('projects/merge_requests/widget/open/rebase', rebase_in_progress: true))}")
merge_request_widget.rebaseInProgress(); merge_request_widget.rebaseInProgress();
...@@ -20,7 +20,10 @@ ...@@ -20,7 +20,10 @@
- elsif !@merge_request.can_be_merged_by?(current_user) - elsif !@merge_request.can_be_merged_by?(current_user)
= render 'projects/merge_requests/widget/open/not_allowed' = render 'projects/merge_requests/widget/open/not_allowed'
- elsif @project.merge_requests_ff_only_enabled - elsif @project.merge_requests_ff_only_enabled
= render 'projects/merge_requests/widget/open/ff_accept' - if @merge_request.ff_merge_possible?
= render 'projects/merge_requests/widget/open/ff_accept'
- else
= render 'projects/merge_requests/widget/open/rebase'
- elsif @merge_request.can_be_merged? - elsif @merge_request.can_be_merged?
= render 'projects/merge_requests/widget/open/accept' = render 'projects/merge_requests/widget/open/accept'
......
- if @merge_request.ff_merge_possible? - status_class = @ci_commit ? " ci-#{@ci_commit.status}" : nil
= form_for [:ff_merge, @project.namespace.becomes(Namespace), @project, @merge_request], remote: true, method: :post, html: { class: 'accept-mr-form js-requires-input' } do |f|
= hidden_field_tag :authenticity_token, form_authenticity_token = form_for [:merge, @project.namespace.becomes(Namespace), @project, @merge_request], remote: true, method: :post, html: { class: 'accept-mr-form js-requires-input' } do |f|
.accept-merge-holder.clearfix.js-toggle-container = hidden_field_tag :authenticity_token, form_authenticity_token
.accept-action .accept-merge-holder.clearfix.js-toggle-container
= f.button class: "btn btn-create accept-mr" do .accept-action
- if @ci_commit && @ci_commit.active?
%span.btn-group
= button_tag class: "btn btn-create js-merge-button merge_when_build_succeeds" do
Merge When Build Succeeds
= button_tag class: "btn btn-success dropdown-toggle", 'data-toggle' => 'dropdown' do
%span.caret
%span.sr-only
Select Merge Moment
%ul.js-merge-dropdown.dropdown-menu.dropdown-menu-right{ role: 'menu' }
%li
= link_to "#", class: "merge_when_build_succeeds" do
= icon('check fw')
Merge When Build Succeeds
%li
= link_to "#", class: "accept_merge_request" do
= icon('warning fw')
Merge Immediately
- else
= f.button class: "btn btn-create btn-grouped js-merge-button accept_merge_request #{status_class}" do
Accept Merge Request Accept Merge Request
- if @merge_request.can_remove_source_branch?(current_user)
.accept-control.checkbox
= label_tag :should_remove_source_branch, class: "remove_source_checkbox" do
= check_box_tag :should_remove_source_branch
Remove source branch
.accept-control.right
Fast-forward merge without creating merge commit
= hidden_field_tag :merge_when_build_succeeds, "", autocomplete: "off"
= hidden_field_tag :ff, "1"
.accept-control :javascript
Fast-forward merge without creating merge commit $('.accept-mr-form').on('ajax:send', function() {
- else $(".accept-mr-form :input").disable();
= form_for [:rebase, @project.namespace.becomes(Namespace), @project, @merge_request], });
remote: true, method: :post, html: { class: 'accept-mr-form js-requires-input' } do |f|
= hidden_field_tag :authenticity_token, form_authenticity_token
.accept-merge-holder.clearfix.js-toggle-container
- if @merge_request.target_project.merge_requests_rebase_enabled && can_rebase?(@merge_request.source_project, @merge_request.source_branch)
- if @merge_request.rebase_in_progress?
%h4 Rebase in progress... It can take a while. Reload at will.
- else
.accept-action
= f.button class: "btn btn-reopen rebase-mr" do
Rebase onto #{@merge_request.target_branch}
.accept-control
Fast-forward merge is not possible. Branch must be rebased first
:coffeescript $('.accept_merge_request').on('click', function() {
$('.accept-mr-form').on 'ajax:before', -> $('.js-merge-button').html("<i class='fa fa-spinner fa-spin'></i> Merge in progress");
btn = $('.accept-mr') });
btn.disable()
btn.html("<i class='fa fa-spinner fa-spin'></i> Merge in progress")
$('.rebase-mr-form').on 'ajax:before', -> $('.merge_when_build_succeeds').on('click', function() {
btn = $('.rebase-mr') $("#merge_when_build_succeeds").val("1");
btn.disable() });
btn.html("<i class='fa fa-spinner fa-spin'></i> Rebase in progress. It could take some time")
- if #{@merge_request.rebase_in_progress?} $('.js-merge-dropdown a').on('click', function(e) {
$ -> e.preventDefault();
merge_request_widget.rebaseInProgress() $(this).closest("form").submit();
});
...@@ -5,7 +5,10 @@ ...@@ -5,7 +5,10 @@
- should_remove_source_branch = @merge_request.merge_params["should_remove_source_branch"].present? - should_remove_source_branch = @merge_request.merge_params["should_remove_source_branch"].present?
%p %p
= succeed '.' do = succeed '.' do
The changes will be merged into - if @merge_request.merge_params["ff"].present?
The changes will be fast-forward merged into
- else
The changes will be merged into
%span.label-branch= @merge_request.target_branch %span.label-branch= @merge_request.target_branch
- if should_remove_source_branch - if should_remove_source_branch
The source branch will be removed. The source branch will be removed.
......
- if @merge_request.rebase_in_progress? || (defined?(rebase_in_progress) && rebase_in_progress)
%h4
= icon("spinner spin")
Rebase in progress&hellip;
%p
This merge request is in the process of being rebased, during which time it is locked and cannot be closed.
:javascript
$(function() {
merge_request_widget.rebaseInProgress()
});
- elsif !@merge_request.target_project.merge_requests_rebase_enabled || !can_push_branch?(@merge_request.source_project, @merge_request.source_branch)
%h4
= icon("exclamation-triangle")
Fast-forward merge is not possible
%p
Please rebase this branch on
%span.label-branch= @merge_request.target_branch
and try again.
- else
= form_for [:rebase, @project.namespace.becomes(Namespace), @project, @merge_request], remote: true, method: :post, html: { class: 'rebase-mr-form js-requires-input' } do |f|
= hidden_field_tag :authenticity_token, form_authenticity_token
.accept-merge-holder.clearfix.js-toggle-container
.accept-action
= f.button class: "btn btn-reopen js-rebase-button" do
Rebase onto #{@merge_request.target_branch}
.accept-control
Fast-forward merge is not possible. Branch must be rebased first
:javascript
$('.rebase-mr-form').on('ajax:send', function() {
$('.rebase-mr-form :input').disable();
});
$('.js-rebase-button').on('click', function() {
$('.js-rebase-button').html("<i class='fa fa-spinner fa-spin'></i> Rebase in progress");
});
...@@ -606,7 +606,6 @@ Rails.application.routes.draw do ...@@ -606,7 +606,6 @@ Rails.application.routes.draw do
post :toggle_subscription post :toggle_subscription
post :approve post :approve
post :rebase post :rebase
post :ff_merge
end end
collection do collection 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