Skip to content

Label System

Auto Merge manages MR labels declaratively using a desired-state model. It computes the target label set for each MR and applies only the diff.

Status labels use the scoped Auto-Merge:: prefix, so GitLab keeps exactly one of them on an MR. Each names one hold that needs human attention. A deliberate wait (pipeline running, rebase needed, rebasing) and a GitLab-native state (draft, approved) carry no label.

Label in GitLab Meaning
Auto-Merge::Has conflicts Has merge conflicts, needs manual resolution
Auto-Merge::Waiting for approval No approval yet, a reviewer must approve it
Auto-Merge::Unresolved discussions Has open blocking discussions
Auto-Merge::Pipeline failed Pipeline failed (or was skipped) and needs attention
Auto-Merge::Blocked by CI GitLab blocks the merge on CI despite a green pipeline
Auto-Merge::Waiting for manual job The pipeline waits for a manual job a human has to start
Auto-Merge::Last pipeline failed The last completed pipeline failed on the code the MR still carries
Auto-Merge::Repeated pipeline failure Out of the merge queue after repeated pipeline failures on the same code
Auto-Merge::Waiting for dependency A merge request the description declares with blocked-by:, depends-on: or waits-for: is not merged

User labels have no :: scope, so several can be set on one MR at once.

Label in GitLab Meaning Second switch
Merge First Prioritizes the MR, processed before every MR of its target branch except a main fix —
Merge Last Lowest priority class, see the queue order below —
Keep Pipeline Pipeline will not be cancelled by Auto Merge checkbox Keep Pipeline in the Auto-Merge section of the MR description
Skip Auto-Merge Ignored by Auto Merge, no rebase, merge, or pipeline management checkbox Skip Auto-Merge in the same section

Merge First also lets Auto Merge cancel lower-priority pipelines when runners are scarce.

Every protected target branch has a queue of its own. Each queue sorts by four priority classes: a title starting with Main fix: , then Merge First or Priority::High, then no matched priority label, then Priority::Low or Merge Last. Within a class, older MRs come first. The title prefix (MAIN_FIX_TITLE_PREFIX) and the Priority::* labels are configurable per deployment.

An MR takes the highest priority class among its own and those of the open MRs stacked on it (MRs whose unprotected target branch is its source branch), transitively over the whole stack. The Auto-Merge section of its description and the dashboard name the MR the class is inherited from. Merge First and Merge Last on the MR itself pin its priority class; only a main fix stacked on it lifts it, because a red default branch holds every merge.

Keep Pipeline and Skip Auto-Merge are the only user labels Auto Merge writes, and a checkbox click is the only thing that makes it write them. Every run compares checkbox and label and acts on the outcome in that same run.

The Auto-Merge section of the MR description states the MR’s position in the merge queue. Auto Merge updates it as MRs ahead of it merge or get reprioritized.

Draft MRs receive special treatment:

  1. Running pipelines are cancelled
  2. All Auto Merge labels are removed
  3. Excluded from merge queue and rebase

When marked as ready, the MR re-enters normal processing.

  1. MR is opened or updated
  2. Auto Merge categorizes the MR (approved? pipeline status? conflicts?)
  3. Desired labels are computed
  4. Diff between current and desired labels is applied
  5. Outdated status labels are removed, new ones added

This desired-state approach prevents label flickering that would occur with imperative add/remove logic.