Fast forward merge: basic implemenation[ci skip]
This commit is contained in:
parent
dede5f0188
commit
7af585f166
8 changed files with 94 additions and 0 deletions
|
@ -344,6 +344,7 @@ class ProjectsController < Projects::ApplicationController
|
|||
:tag_list,
|
||||
:visibility_level,
|
||||
:template_name,
|
||||
:merge_method,
|
||||
|
||||
project_feature_attributes: %i[
|
||||
builds_access_level
|
||||
|
|
|
@ -1557,6 +1557,23 @@ class Project < ActiveRecord::Base
|
|||
persisted? && path_changed?
|
||||
end
|
||||
|
||||
def merge_method
|
||||
if self.merge_requests_ff_only_enabled
|
||||
:ff
|
||||
else
|
||||
:merge
|
||||
end
|
||||
end
|
||||
|
||||
def merge_method=(method)
|
||||
self.merge_requests_ff_only_enabled = method.to_s == "ff"
|
||||
end
|
||||
|
||||
def ff_merge_must_be_possible?
|
||||
self.merge_requests_ff_only_enabled
|
||||
end
|
||||
# alias_method :merge_requests_ff_only_enabled?, :merge_requests_ff_only_enabled
|
||||
|
||||
private
|
||||
|
||||
def storage
|
||||
|
|
|
@ -854,6 +854,25 @@ class Repository
|
|||
end
|
||||
end
|
||||
|
||||
def ff_merge(user, source, target_branch, merge_request: nil)
|
||||
our_commit = rugged.branches[target_branch].target
|
||||
their_commit =
|
||||
if source.is_a?(Gitlab::Git::Commit)
|
||||
source.raw_commit
|
||||
else
|
||||
rugged.lookup(source)
|
||||
end
|
||||
|
||||
raise 'Invalid merge target' if our_commit.nil?
|
||||
raise 'Invalid merge source' if their_commit.nil?
|
||||
|
||||
with_branch(user, target_branch) do |start_commit|
|
||||
merge_request&.update(in_progress_merge_commit_sha: their_commit.oid)
|
||||
|
||||
their_commit.oid
|
||||
end
|
||||
end
|
||||
|
||||
def revert(
|
||||
user, commit, branch_name, message,
|
||||
start_branch_name: nil, start_project: project)
|
||||
|
|
|
@ -13,6 +13,11 @@ class MergeRequestEntity < IssuableEntity
|
|||
expose :target_branch
|
||||
expose :target_project_id
|
||||
|
||||
expose :ff_only_enabled do |merge_request|
|
||||
merge_request.project.merge_requests_ff_only_enabled
|
||||
end
|
||||
|
||||
|
||||
# Events
|
||||
expose :merge_event, using: EventEntity
|
||||
expose :closed_event, using: EventEntity
|
||||
|
|
24
app/services/merge_requests/ff_merge_service.rb
Normal file
24
app/services/merge_requests/ff_merge_service.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
module MergeRequests
|
||||
# MergeService class
|
||||
#
|
||||
# Do git fast-forward merge and in case of success
|
||||
# mark merge request as merged and execute all hooks and notifications
|
||||
# Executed when you do fast-forward merge via GitLab UI
|
||||
#
|
||||
class FfMergeService < MergeRequests::MergeService
|
||||
private
|
||||
|
||||
def commit
|
||||
repository.ff_merge(current_user,
|
||||
source,
|
||||
merge_request.target_branch,
|
||||
merge_request: merge_request)
|
||||
rescue Gitlab::Git::HooksService::PreReceiveError => e
|
||||
raise MergeError, e.message
|
||||
rescue StandardError => e
|
||||
raise MergeError, "Something went wrong during merge: #{e.message}"
|
||||
ensure
|
||||
merge_request.update(in_progress_merge_commit_sha: nil)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -11,6 +11,11 @@ module MergeRequests
|
|||
attr_reader :merge_request, :source
|
||||
|
||||
def execute(merge_request)
|
||||
if project.merge_requests_ff_only_enabled && !self.is_a?(FfMergeService)
|
||||
FfMergeService.new(project, current_user, params).execute(merge_request)
|
||||
return
|
||||
end
|
||||
|
||||
@merge_request = merge_request
|
||||
|
||||
unless @merge_request.mergeable?
|
||||
|
|
|
@ -1,5 +1,27 @@
|
|||
- form = local_assigns.fetch(:form)
|
||||
|
||||
.form-group
|
||||
= label_tag :merge_method_merge, class: 'label-light' do
|
||||
Merge method
|
||||
.radio
|
||||
= label_tag :project_merge_method_merge do
|
||||
= form.radio_button :merge_method, :merge, class: "js-merge-method-radio"
|
||||
%strong Merge commit
|
||||
%br
|
||||
%span.descr
|
||||
A merge commit is created for every merge, and merging is allowed as long as there are no conflicts.
|
||||
|
||||
.radio
|
||||
= label_tag :project_merge_method_ff do
|
||||
= form.radio_button :merge_method, :ff, class: "js-merge-method-radio"
|
||||
%strong Fast-forward merge
|
||||
%br
|
||||
%span.descr
|
||||
No merge commits are created and all merges are fast-forwarded, which means that merging is only allowed if the branch could be fast-forwarded.
|
||||
%br
|
||||
%span.descr
|
||||
When fast-forward merge is not possible, the user must first rebase locally.
|
||||
|
||||
.form-group
|
||||
.checkbox.builds-feature{ class: ("hidden" if @project && @project.project_feature.send(:builds_access_level) == 0) }
|
||||
= form.label :only_allow_merge_if_pipeline_succeeds do
|
||||
|
|
|
@ -412,6 +412,7 @@ Project:
|
|||
- last_repository_updated_at
|
||||
- ci_config_path
|
||||
- delete_error
|
||||
- merge_requests_ff_only_enabled
|
||||
Author:
|
||||
- name
|
||||
ProjectFeature:
|
||||
|
|
Loading…
Reference in a new issue