Commit bd2a29a8 authored by Marin Jankovski's avatar Marin Jankovski

Add option of rebasing before merging.

parent 298ae61d
......@@ -122,6 +122,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
if @merge_request.open? && @merge_request.can_be_merged?
@merge_request.should_remove_source_branch = params[:should_remove_source_branch]
@merge_request.should_rebase = params[:should_rebase]
@merge_request.automerge!(current_user, params[:commit_message])
@status = true
else
......
......@@ -202,7 +202,8 @@ class ProjectsController < ApplicationController
params.require(:project).permit(
:name, :path, :description, :issues_tracker, :tag_list,
:issues_enabled, :merge_requests_enabled, :snippets_enabled, :issues_tracker_id, :default_branch,
:wiki_enabled, :visibility_level, :import_url, :last_activity_at, :namespace_id, :merge_requests_template
:wiki_enabled, :visibility_level, :import_url, :last_activity_at, :namespace_id, :merge_requests_template,
:merge_requests_rebase_enabled
)
end
end
......@@ -40,6 +40,9 @@ class MergeRequest < ActiveRecord::Base
attr_accessor :should_remove_source_branch
# If true, merge request should rebase before merging
attr_accessor :should_rebase
# When this attribute is true some MR validation is ignored
# It allows us to close or modify broken merge requests
attr_accessor :allow_broken
......
......@@ -24,6 +24,11 @@
= label_tag :should_remove_source_branch, class: "checkbox" do
= check_box_tag :should_remove_source_branch
Remove source-branch
- if @merge_request.source_project.merge_requests_rebase_enabled && !@merge_request.for_fork?
.remove_branch_holder.pull-left
= label_tag :should_rebase, class: "checkbox" do
= check_box_tag :should_rebase
Rebase before merge
.js-toggle-container
%label
%i.fa.fa-edit
......
......@@ -2,6 +2,8 @@ module Gitlab
module Satellite
# GitLab server-side merge
class MergeAction < Action
include Gitlab::Popen
attr_accessor :merge_request
def initialize(user, merge_request)
......@@ -27,6 +29,16 @@ module Gitlab
def merge!(merge_commit_message = nil)
in_locked_and_timed_satellite do |merge_repo|
prepare_satellite!(merge_repo)
if merge_request.should_rebase
if rebase_in_satellite!(merge_repo)
merge_repo.git.push(default_options, :origin, merge_request.target_branch)
return true
else
prepare_satellite!(merge_repo)
end
end
if merge_in_satellite!(merge_repo, merge_commit_message)
# push merge back to bare repo
# will raise CommandFailed when push fails
......@@ -133,6 +145,25 @@ module Gitlab
handle_exception(ex)
end
def rebase_in_satellite!(repo)
update_satellite_source_and_target!(repo)
repo.git.checkout(default_options({b: true}), merge_request.source_branch, "source/#{merge_request.source_branch}")
repo.git.merge(default_options({no_ff: true}), "origin/#{merge_request.target_branch}")
output, status = popen(%W(git rebase origin/#{merge_request.target_branch}), repo.working_dir)
if status == 0
Gitlab::AppLogger.info "Rebasing before merge in #{merge_request.source_project.path_with_namespace} MR!#{merge_request.id}: #{output}."
repo.git.checkout(default_options, merge_request.target_branch)
repo.git.merge(default_options, "source/#{merge_request.source_branch}")
else
repo.git.rebase(default_options, "--abort")
Gitlab::AppLogger.info "Rebasing in in #{merge_request.source_project.path_with_namespace} MR!#{merge_request.id} aborted, rebase manually."
false
end
rescue Grit::Git::CommandFailed => ex
handle_exception(ex)
end
# Assumes a satellite exists that is a fresh clone of the projects repo, prepares satellite for merges, diffs etc
def update_satellite_source_and_target!(repo)
repo.remote_add('source', merge_request.source_project.repository.path_to_repo)
......
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