Reject auto_merge push option without merge permission

What does this MR do and why?

git push -o merge_request.auto_merge (and the merge_request.merge_when_pipeline_succeeds alias) was accepted from a user who lacks permission to merge the target branch. The auto-merge was recorded with that user as merge_user, and because they cannot merge, the merge request became unmergeable for everyone: a user who does hold merge permission saw "You are not allowed to merge this merge request" with no Merge button, and the MR stayed open until the auto-merge was cancelled.

The cause is in MergeRequests::PushOptionsHandlerService. It sets auto_merge_enabled (an alias for the merge_when_pipeline_succeeds column) directly through BuildService/CreateService. That writes the auto-merge straight onto the record and skips the permission check AutoMergeService applies when auto-merge is enabled through the normal path.

This MR guards the auto-merge push options behind the same check MergeRequest#can_be_merged_by? uses (Gitlab::UserAccess#can_update_branch?). When the pushing user cannot merge the target branch:

  • the auto-merge is not recorded, so the merge request is never left in the unmergeable state, and
  • an explanatory error is added, which surfaces on the git remote: channel naming the project, branch, and missing permission.

This implements the first (and preferred) option from #623038 (closed) — reject the option at push time with a remote: message. The second half of the issue — that detailed_merge_status reports mergeable while merge_error holds a permission refusal — lives in the mergeability-status code and is better addressed as a separate follow-up.

Related to #623038 (closed).

Behavior

Before: git push -o merge_request.auto_merge from a Developer against a target branch that only Maintainers may merge → the auto-merge is recorded silently and the MR is stuck unmergeable.

After: the same push does not enable auto-merge and prints a line such as:

remote: merge_request.auto_merge was not applied: you do not have permission to merge into group/project:main

The branch push itself still succeeds, and when combined with merge_request.create the merge request is still created — only the auto-merge is withheld.

How to set up and validate locally

  1. Protect a project's default branch with "Allowed to merge" set to Maintainers (so the Developer role is excluded).
  2. As a Developer, run git push -o merge_request.create -o merge_request.auto_merge.
  3. Confirm the merge request is created, auto-merge is not enabled, and the remote: output names the branch and the missing permission.

Specs:

bin/rspec spec/services/merge_requests/push_options_handler_service_spec.rb
Edited by Bobby Nandigam

Merge request reports

Loading
Loading