Validate branch existence on merge request creation
Summary
Adds an on: :create model validation to MergeRequest that checks source and target branches actually exist in the repository.
Previously, only the UI enforced this via BuildService, while the API allowed creating MRs with non-existent branches, resulting in broken MRs with null diff_refs and misleading has_conflicts: true states.
Closes #591660
What does this MR do?
- Adds
validate :validate_branch_existence, on: :createto theMergeRequestmodel - The validation checks
source_branch_exists?andtarget_branch_exists?using existing model methods - Adds
skip_branch_existence_checkattr_accessor to bypass validation in test factories (similar pattern to existingallow_broken) - Skipped when
allow_broken,importing_or_transitioning?, orclosed_or_merged_without_fork?(matching existing validation guards) - Gated behind the
validate_merge_request_branch_existencefeature flag (gitlab_com_derisk, disabled by default) for safe incremental rollout - Adds model-level and API integration specs with feature flag enabled/disabled contexts
Feature flag
This MR is gated behind the validate_merge_request_branch_existence feature flag:
-
Type:
gitlab_com_derisk - Default: disabled
-
Actor:
source_project - Rollout issue: #594430
Why model-level?
The validation belongs on the model to protect all creation paths (API, services, console, etc.), not just specific endpoints. A skip_branch_existence_check flag (set true in the factory) prevents breaking existing tests that create MRs with non-existent branch names.
Note on Danger bot warning
The Danger bot warns about new validations breaking existing records. This validation is on: :create only — it will not affect any existing merge requests, only new ones being created.
MR acceptance checklist
- Tests added for model validation with feature flag on/off
- Tests added for API endpoint with feature flag on/off
- Tests added for CreateService with feature flag on/off
-
Follows existing validation patterns (
unless: [:allow_broken, ...]) -
Uses
_()for i18n on error messages - Feature flag YAML definition created
- Rollout issue created