Commit 8a7917fc authored by Alain Takoudjou's avatar Alain Takoudjou

NXD: Apply patches for MR with more than one commits will ff_merge

If MR has more than one commit, it's possible to do fast-forward merge when
the MR branch is rebased.
parent 98f4fb67
......@@ -159,6 +159,13 @@ export default {
return this.mr.canRemoveSourceBranch;
},
ffMergePossible() {
if (this.glFeatures.mergeRequestWidgetGraphql) {
return this.stateData.ffMergePossible;
}
return this.mr.ffMergePossible;
},
commits() {
if (this.glFeatures.mergeRequestWidgetGraphql) {
return this.state.commitsWithoutMergeCommits.nodes;
......@@ -175,10 +182,16 @@ export default {
},
ApplyPatchButtonText() {
return __('Apply Patch ');
if (this.mr.commitsCount === 1) {
return __('Apply Patch ');
}
return __('Fast-forward Merge ');
},
isApplyPatchAllowed() {
return this.mr.commitsCount !== 1 || this.isMergeButtonDisabled;
isApplyPatchDisabled() {
if (this.mr.commitsCount === 1) {
return this.isMergeButtonDisabled;
}
return !this.ffMergePossible || this.isMergeButtonDisabled;
},
preferredAutoMergeStrategy() {
if (this.glFeatures.mergeRequestWidgetGraphql) {
......@@ -539,7 +552,7 @@ export default {
class="patch-merge-request accept-merge-request"
data-testid="apply-button"
:variant="mergeButtonVariant"
:disabled="isApplyPatchAllowed"
:disabled="isApplyPatchDisabled"
:loading="isMakingRequest"
data-qa-selector="apply_patch_button"
@click="handleMergeButtonClick(false, false, true)"
......
......@@ -16,6 +16,7 @@ query getState($projectPath: ID!, $iid: String!) {
status
warnings
}
ffMergePossible
shouldBeRebased
sourceBranchExists
state
......
......@@ -17,6 +17,7 @@ fragment ReadyToMerge on Project {
mergeWhenPipelineSucceeds
commitCount
diffHeadSha
ffMergePossible
userPermissions {
removeSourceBranch
}
......
......@@ -144,6 +144,7 @@ export default class MergeRequestStore {
this.projectArchived = data.project_archived;
this.isSHAMismatch = this.sha !== data.diff_head_sha;
this.shouldBeRebased = Boolean(data.should_be_rebased);
this.ffMergePossible = Boolean(data.ff_merge_possible);
this.workInProgress = data.work_in_progress;
}
......@@ -187,6 +188,7 @@ export default class MergeRequestStore {
this.isPipelineFailed = this.ciStatus === 'failed' || this.ciStatus === 'canceled';
this.isSHAMismatch = this.sha !== mergeRequest.diffHeadSha;
this.shouldBeRebased = mergeRequest.shouldBeRebased;
this.ffMergePossible = mergeRequest.ffMergePossible;
this.workInProgress = mergeRequest.workInProgress;
this.mergeRequestState = mergeRequest.state;
......
......@@ -40,6 +40,9 @@ module Mutations
required: false,
default_value: false,
description: 'Squash commits on the source branch before merge.'
argument :apply_patch, ::GraphQL::BOOLEAN_TYPE,
required: false,
description: 'Merge with apply patche button enabled.'
def resolve(project_path:, iid:, **args)
Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/4796')
......
......@@ -91,6 +91,8 @@ module Types
description: 'Indicates if members of the target project can push to the fork.'
field :should_be_rebased, GraphQL::BOOLEAN_TYPE, method: :should_be_rebased?, null: false, calls_gitaly: true,
description: 'Indicates if the merge request will be rebased.'
field :ff_merge_possible, GraphQL::BOOLEAN_TYPE, method: :ff_merge_possible?, null: false, calls_gitaly: true,
description: 'Indicates if the ff merge is possible.'
field :rebase_commit_sha, GraphQL::STRING_TYPE, null: true,
description: 'Rebase commit SHA of the merge request.'
field :rebase_in_progress, GraphQL::BOOLEAN_TYPE, method: :rebase_in_progress?, null: false, calls_gitaly: true,
......
......@@ -116,6 +116,7 @@ class MergeRequest < ApplicationRecord
has_many :reviews, inverse_of: :merge_request
KNOWN_MERGE_PARAMS = [
:apply_patch,
:auto_merge_strategy,
:should_remove_source_branch,
:force_remove_source_branch,
......
......@@ -86,21 +86,31 @@ module MergeRequests
log_info("Git merge started on JID #{merge_jid}")
mr_1patch = merge_request.commits.size == 1
do_apply = params[:apply_patches] || mr_1patch
do_merge = !do_apply
patch = merge_request.commits.reverse.first
commit_id = do_merge ? try_merge \
: repository.cherry_pick(current_user, repository.commit(patch.sha), merge_request.target_branch, commit_message,
start_branch_name: nil, start_project: project, dry_run: false)
ff_merged = false
if params[:apply_patch]
if mr_1patch
patch = merge_request.commits.reverse.first
commit_id = repository.cherry_pick(current_user, repository.commit(patch.sha), merge_request.target_branch,
commit_message, start_branch_name: nil, start_project: project, dry_run: false)
else
# ff_merge
ff_merged = true
try_ff_merge
end
else
commit_id = try_merge
end
if commit_id
log_info("Git merge finished on JID #{merge_jid} commit #{commit_id}")
merge_request.update!(merge_commit_sha: commit_id)
elsif ff_merged
log_info("Git merge finished on JID #{merge_jid}")
else
raise_error(GENERIC_ERROR_MESSAGE)
end
merge_request.update!(merge_commit_sha: commit_id)
ensure
merge_request.update_and_mark_in_progress_merge_commit_sha(nil)
end
......@@ -117,6 +127,20 @@ module MergeRequests
raise_error(GENERIC_ERROR_MESSAGE)
end
def try_ff_merge
repository.ff_merge(current_user,
source,
merge_request.target_branch,
merge_request: merge_request)
rescue Gitlab::Git::PreReceiveError => e
raise MergeError,
"Something went wrong during merge pre-receive hook. #{e.message}".strip
rescue StandardError => e
handle_merge_error(log_message: e.message)
raise_error(GENERIC_ERROR_MESSAGE)
end
def after_merge
log_info("Post merge started on JID #{merge_jid} with state #{state}")
MergeRequests::PostMergeService.new(project: project, current_user: current_user).execute(merge_request)
......
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