Map states of MR merge widget/button
As part of making the merge button lovable, we should first understand what we're dealing with, by mapping the merge widget:
- States
- Actions
- Information
I'm thinking about mapping this visually, using a diagram in a format that is consumable and maintainable by anyone.
Mapping
Description of the merge widget states
Legend
- States:
-
⏸ Blocked state(s) -
🔃 Loading state(s) -
✅ Success state(s) -
😐 Resting state(s) -
🔴 Error state(s) -
🐛 Possible bug
-
- UI elements:
-
💬 Text -
▶ ️ Button -
🔗 Link -
🔘 Form input -
⚠ ️ Error/warning alert -
ℹ ️ Info/success alert -
❓ Tooltip
-
States
-
🔃 Loading-
🔴 Failed to load-
⚠ ️ Unable to load the merge request widget. Try reloading the page.
-
-
-
🔃 Checking status- When is this triggered?
-
🔴 Failed to check status-
⚠ ️ Something went wrong. Please try again.
-
-
⏸ Cannot be merged- Using a secondary Geo node (only in GitLab Premium+)
-
💬 Merge requests are read-only in a secondary Geo node -
▶ ️ Merge (disabled)
-
- Has denied licenses (only in GitLab Premium+)
-
💬 You can merge after removing denied licenses -
▶ ️ Merge (disabled)
-
- Project is archived
-
💬 This project is archived, write access has been disabled -
▶ ️ Merge (disabled)
-
- Source OR target branch is missing
-
💬 {Source|Target} branch does not exist. Please restore it or use a different {source|target} branch [?]-
❓ Tooltip: If the {source|target} branch exists in your local repository, you can merge this merge request manually using the command line
-
-
▶ ️ Merge (disabled) - If target branch is missing AND MR is reopened:
-
💬 We cannot render this merge request properly because {target branch name} does not exist in {project path} Please close Merge Request or change branches with existing one
-
-
- Source branch has no changes
-
💬 Merge requests are a place to propose changes you have made to a project and discuss those changes with others. Interested parties can even contribute by pushing commits if they want to. Currently there are no changes in this merge request's source branch. Please push new commits or use a different branch. - If user can push to source branch:
-
▶ ️ Create file — go to “New file” screen on the source branch.
-
-
- Merge-ability hasn’t been checked OR is checking
-
💬 Checking if merge request can be merged… -
▶ ️ Merge (disabled)
-
- Has conflicts
-
▶ ️ Merge (disabled) - If FF-merge strategy:
-
💬 Fast-forward merge is not possible. To merge this request, first rebase locally.
-
- If merge commit strategy:
- If user can write to both branches:
-
💬 There are merge conflicts -
▶ ️ Merge locally — open modal with command line instructions. -
▶ ️ Resolve conflicts — go to conflict resolution UI.
-
- If user can only merge to target branch:
-
💬 There are merge conflicts -
▶ ️ Merge locally — open modal with command line instructions.
-
- If user can only push to source branch:
-
💬 There are merge conflicts. Resolve these conflicts or ask someone with write access to this repository to merge it locally -
▶ ️ Resolve conflicts — go to conflict resolution UI.
-
- If user cannot write to either branch:
-
💬 There are merge conflicts. Resolve these conflicts or ask someone with write access to this repository to merge it locally
-
- If user can write to both branches:
-
- Must be rebased (if FF-merge strategy AND source branch is behind target branch)
- If user cannot push to source branch:
-
💬 Fast-forward merge is not possible. Rebase the source branch onto {target branch name} to allow this merge request to be merged.
-
- If user can push to source branch:
-
💬 Fast-forward merge is not possible. Rebase the source branch onto the target branch. -
▶ ️ Rebase — go to “Rebasing” state.
-
-
🔃 Rebasing-
▶ ️ Merge (disabled) -
💬 Rebase in progress -
✅ Success — go to “Can be merged” state. -
🔴 Failed to rebase-
💬 Rebase failed. Please rebase locally. -
💬 Merge failed: Rebase failed. Please rebase locally. Please try again. -
⚠ ️ Something went wrong. Please try again. - If user can push to source branch:
-
▶ ️ Rebase — go to “Rebasing” state.
-
-
-
- If user cannot push to source branch:
- Pipelines must succeed AND (pipeline failed OR was canceled)
-
▶ ️ Merge (disabled) -
💬 The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure
-
- Marked as draft
- If user can edit the MR
-
▶ ️ Merge (disabled) -
▶ ️ Mark as ready — go to “Marking as ready” state.
-
-
💬 This merge request is still a draft. Draft merge requests can't be merged. -
🔃 Marking as ready-
▶ ️ Mark as ready (loading, disabled) -
✅ Marked as ready-
ℹ ️ The merge request can now be merged.
-
-
🔴 Failed to mark as ready-
⚠ ️ Something went wrong. Please try again.
-
-
- If user can edit the MR
- All threads must be resolved AND has unresolved thread AND not set to auto-merge
-
▶ ️ Merge (disabled) -
💬 Before this can be merged, one or more threads must be resolved. -
▶ ️ Jump to first unresolved thread — scroll to first unresolved thread. - If user can create issues AND issues feature is enabled
-
▶ ️ Resolve all threads in new issue — go to “New issue” screen on target project with prefilled contents.
-
-
- Pipelines must succeed AND pipeline is blocked (waiting for manual action)
-
▶ ️ Merge (disabled) -
💬 Pipeline blocked. The pipeline for this merge request requires a manual action to proceed.
-
- If SHA mismatch (source branch HEAD changed just now) AND user can merge to target branch — see “Can be merged” state.
- Auto-merge failed
-
💬 Merge failed: {merge error}. Please try again. -
💬 This merge request failed to be merged automatically -
▶ ️ Refresh — changes to loading and disabled, goes to start.
-
- User cannot merge to target branch
-
▶ ️ Merge (disabled) -
💬 Ready to be merged automatically. Ask someone with write access to this repository to merge this request
-
- Pipelines must succeed AND no pipeline has ran
-
▶ ️ Merge (disabled) -
💬 A CI/CD pipeline must run and be successful before merge. [?]
-
- Missing required approvals AND no pipeline is running (only in GitLab Premium+)
-
▶ ️ Merge (disabled) -
💬 You can only merge once this merge request is approved. -
🐛 This should be shown even if there’s a pipeline running.
-
- Blocked by another MR AND no pipeline is running (only in GitLab Premium+)
-
▶ ️ Merge (disabled) -
💬 You can only merge once the items above are resolved. -
🐛 This should be shown even if there’s a pipeline running.
-
- Using a secondary Geo node (only in GitLab Premium+)
-
😐 Can be merged (AND user can merge to target branch)- Regular merge — If no pipeline is running:
-
▶ ️ Merge — go to “Merging” state- Disabled if any of these are true:
- Squash commit message is empty
- Merge commit message is empty
- Missing required approvals
- MR is not mergeable for some reason
- Is merging (see state below)
- If pipeline failed, the button is styled as danger
- Disabled if any of these are true:
-
- MWPS — If a pipeline is running:
- If pipelines must succeed:
-
▶ ️ Merge when pipeline succeeds — go to “Set to auto-merge” state.- Disabled if … (see
▶ ️ Merge button in “Can be merged” state)
- Disabled if … (see
-
- MWPS dropdown — if pipelines are not required to succeed
- Disabled if … (see
▶ ️ Merge button in “Can be merged” state) -
▶ ️ Merge when pipeline succeeds — go to “Set to auto-merge” state. -
▶ ️ Merge immediately — go to “Merging” state.
- Disabled if … (see
- If pipelines must succeed:
- Merge train actions — if merged results pipelines is enabled AND merge trains is enabled (only in GitLab Premium+)
-
🐛 #300663 (closed) Merge train actions don’t appear if pipeline is blocked (waiting for manual action). - MT dropdown — if no (detached) pipeline is running
- Disabled if … (see
▶ ️ Merge button in “Can be merged” state) -
▶ ️ {Start|Add to} merge train — go to “Set to auto-merge” state. -
▶ ️ Merge immediately — go to “Merge immediately confirmation modal” state.
- Disabled if … (see
- MTWPS — if a (detached) pipeline is running
- If pipelines must succeed:
-
▶ ️ {Start|Add to} merge train when pipeline succeeds — go to “Set to auto-merge” state.- Disabled if … (see
▶ ️ Merge button in “Can be merged” state)
- Disabled if … (see
-
- MTWPS dropdown — if a (detached) pipeline running AND pipelines are not required to succeed
- Disabled if … (see
▶ ️ Merge button in “Can be merged” state) -
▶ ️ {Start|Add to} merge train when pipeline succeeds — go to “Set to auto-merge” state. -
▶ ️ Merge immediately — go to “Merge immediately confirmation modal” state.
- Disabled if … (see
-
💬 This action will {start a merge train|add the merge request to the merge train} when pipeline [{pipeline iid}] succeeds. [More information] -
⏸ Merge immediately confirmation modal-
💬 Merging immediately isn't recommended as it may negatively impact the existing merge train. Read the [documentation] for more information.-
🔗 Link to https://docs.gitlab.com/ee/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.html#immediately-merge-a-merge-request-with-a-merge-train -
🐛 Talks about “existing merge train” even when there’s no merge train.
-
-
💬 Are you sure you want to merge immediately? -
▶ ️ Cancel — close modal. -
▶ ️ Merge immediately — go to “Merging” state.
-
- If pipelines must succeed:
-
- If user can push to source branch AND (is non-protected OR is not the default branch in source project)
-
🔘 Delete source branch- Disabled if merge button is disabled (see
▶ ️ Merge button in “Can be merged” state)-
🐛 Why? It should be accessible even if the merge button is disabled and the MR is not being merged. -
🐛 Other fields, like squash and commit message are not disabled while merging.
-
- Disabled if merge button is disabled (see
-
- If source branch has 2+ new commits:
-
🔘 Squash commits [?]-
❓ Tooltip: What is squashing? -
🔗 Link: https://docs.gitlab.com/ee/user/project/merge_requests/squash_and_merge.html - Checked by default — if project setting is “Encouraged”
- Checked and read-only — if project setting is “Required”
- Unchecked by default — if project setting is “Allowed” (default)
- Unchecked and hidden — if project setting is “Don’t allow”
-
-
- If SHA mismatch (source branch HEAD changed just now)
-
💬 The source branch HEAD has recently changed. Please reload the page and review the changes before merging.-
🐛 I don’t think this is being used?
-
-
💬 New changes were added. [Reload the page to review them] — reloads page in Changes tab.
-
- If FF-merge strategy
-
💬 Fast-forward merge without a merge commit
-
- Edit commit messages:
- If FF-merge strategy AND “Squash commits” is checked:
-
🔗 1 commit will be added to {target branch name}. [Modify commit message]-
🔘 Squash commit message -
▶ ️ Use an existing commit message — open dropdown to select commit message from source branch.
-
-
- If merge commit strategy:
- “Squash commits” is checked:
-
🔗 1 commit and {merge commit count} merge commits will be added to {target branch name}. [Modify commit messages]-
🔘 Squash commit message -
▶ ️ Use an existing commit message — open dropdown to select commit message from source branch. -
🔘 Merge commit message -
🔘 Include merge request description
-
-
- “Squash commits” is unchecked:
-
🔗 {commit count} commits and {merge commit count} merge commits will be added to {target branch name}. [Modify merge commit]-
🔘 Merge commit message -
🔘 Include merge request description
-
-
- “Squash commits” is checked:
- If FF-merge strategy AND “Squash commits” is checked:
- Regular merge — If no pipeline is running:
-
🔃 Setting auto-merge-
▶ ️ {auto-merge button text} (loading, disabled) -
✅ Success — go to “Set to auto-merge” state. -
🔴 Failed to set to auto-merge-
▶ ️ Merge (disabled) -
💬 {error message} Refreshing in {x} seconds to show the updated status… -
▶ ️ Refresh now — changes to loading and disabled, goes to start. -
💬 Merge failed: {error message}. Please try again. -
⚠ ️ Something went wrong. Please try again.
-
-
-
😐 Set to auto-merge- MWPS
-
💬 Set by [{user name}] to be merged automatically when the pipeline succeeds-
🔗 Link to user profile page
-
- If user can merge to target branch OR user is MR author
-
▶ ️ Cancel automatic merge — go to “Cancelling auto-merge” state.
-
-
- MT — if no (detached) pipeline is running
-
💬 Added to the merge train by [{user name}]-
🔗 Link to user profile page
-
- If user can merge to target branch OR user is MR author
-
▶ ️ Remove from merge train — go to “Cancelling auto-merge” state.
-
-
- MTWPS — if a (detached) pipeline is running
-
💬 Set by [{user name}] to {start a|be added to the} merge train when the pipeline succeeds-
🔗 Link to user profile page
-
- If user can merge to target branch OR user is MR author
-
▶ ️ Cancel automatic merge — go to “Cancelling auto-merge” state.
-
-
-
💬 The changes will be merged into [{target branch name}]-
🔗 Link to target branch commits page
-
- If source branch is set for deletion
-
💬 The source branch will be deleted
-
- If source branch is not set for deletion
-
💬 The source branch will not be deleted - If user can push to source branch AND (is non-protected OR is not the default branch in source project)
-
▶ ️ Delete source branch — go to “Setting deletion” state.-
🔃 Setting deletion-
▶ ️ Delete source branch (loading, disabled) -
✅ Success — see “If source branch is set for deletion” -
🔴 Failed to set deletion-
⚠ ️ Something went wrong. Please try again.
-
-
-
-
-
- MWPS
-
🔃 Cancelling auto-merge- If MWPS and MTWPS
-
▶ ️ Cancel automatic merge (loading, disabled)
-
- If MT
-
▶ ️ Remove from merge train (loading, disabled)
-
-
✅ Success — go to “Can be merged” state. -
🔴 Failed to cancel auto-merge-
⚠ ️ Something went wrong. Please try again.
-
- If MWPS and MTWPS
-
🔃 Merging- If current user uses auto-merge’s “Merge immediately” button:
-
▶ ️ Merge in progress (disabled)
-
- If current user uses regular merge:
-
▶ ️ Merge (loading)
-
- If user cannot merge to target branch OR triggered by another user
-
💬 This merge request is in the process of being merged -
💬 The changes will be merged into [{target branch name}]-
🔗 Link to target branch commits page
-
-
-
✅ Success — go to “Merged” state. -
🔴 Failed to merge-
▶ ️ Merge (disabled) -
💬 {error message} Refreshing in {x} seconds to show the updated status… -
▶ ️ Refresh now — changes to loading and disabled, goes to start. -
💬 Merge failed: {error message}. Please try again. -
⚠ ️ Something went wrong while merging this merge request. Please try again.
-
-
🔴 Failed to delete source branch-
⚠ ️ Something went wrong while deleting the source branch. Please try again.
-
- If current user uses auto-merge’s “Merge immediately” button:
-
✅ Merged-
💬 Merged by [{user name}] {timestamp}-
🔗 Link to user profile page
-
- If merge commit strategy AND user can create merge requests:
-
🐛 Could not trigger revert in new fork AND cherry-pick in new fork. Might not be correctly implemented? -
▶ ️ Revert — go to “Revert modal” state.-
❓ Tooltip: Revert this merge request in a new merge request -
⏸ Revert modal-
💬 Revert this merge request This will create a new commit in order to revert existing changes. -
🔘 Revert in branch - If user can push to target project:
-
🔘 Start a new merge request with these changes
-
-
▶ ️ Cancel — close modal. -
▶ ️ Revert — create merge request reverting merge commit. - If user cannot push to target project AND has forked the project:
-
💬 A new branch will be created in your fork and a new merge request will be started.
-
-
-
-
▶ ️ Cherry-pick — go to “Cherry-pick modal” state.-
❓ Tooltip: Cherry-pick this merge request in a new merge request -
⏸ Cherry-pick modal-
💬 Cherry-pick this merge request -
🔘 Pick into branch - If user can push to target project:
-
🔘 Start a new merge request with these changes
-
-
▶ ️ Cancel — close modal. -
▶ ️ Cherry-pick — create merge request with this merge request's merge commit. - If user cannot push to target project AND has forked the project:
-
💬 A new branch will be created in your fork and a new merge request will be started.
-
-
-
-
-
💬 The changes were merged into [{target branch name}] with [{merge commit SHA}]-
🔗 Link to target branch commits page -
🔗 Link to merge commit page
-
- If source branch was deleted AND user cannot push to source branch:
-
💬 The source branch has been deleted -
🐛 This message should be shown to everyone.
-
- If source branch was not deleted AND user can push to source branch AND (is non-protected OR not the default branch in source project)
-
💬 You can delete the source branch now -
▶ ️ Delete source branch — go to “Deleting source branch” state.-
🔃 Deleting source branch-
💬 The source branch is being deleted -
✅ Success — see “If source branch was deleted” -
🔴 Failed to delete source branch-
⚠ ️ Something went wrong. Please try again.
-
-
-
-
-
💬 Closed [{issue iid}]-
🔗 Link to issue page
-
-
-
😐 Closed-
💬 Closed by [{user name}] {timestamp}-
🔗 Link to user profile page
-
-
💬 The changes were not merged into [{target branch name}]-
🔗 Link to target branch commits page
-
-
💬 Did not close [{issue iid}]-
🔗 Link to issue page
-
-
Actions and settings
- Delete source branch
- If set by MR author, the branch is deleted using the author’s user
- If unset by the MR merge, the branch is not deleted
- If set by MR merger, the branch is deleted using the merger's user
- If set by MR author, the branch is deleted using the author’s user
Almost always visible
- Allows fork collaboration — if source branch is from a fork AND MR author allows collaboration
-
💬 Allows commits from members who can merge to the target branch
-
- Issue relationship
- If MR is open:
-
💬 Closes [{issue iid}]-
🔗 Link to issue page
-
-
- If MR is closed:
-
💬 Did not close [{issue iid}]-
🔗 Link to issue page
-
-
- If MR is merged:
-
💬 Closed [{issue iid}]-
🔗 Link to issue page
-
-
-
💬 Mentions [{issue iid}]-
🔗 Link to issue page
-
- If closing issues are not external issues AND closing issues are not assigned AND current user is MR author AND current user can edit issues
- If multiple eligible closing issues:
-
▶ ️ Assign yourself to these issues
-
- If one eligible closing issue:
-
▶ ️ Assign yourself to this issue
-
- If multiple eligible closing issues:
- If MR is open:
- Source branch deletion status — If user cannot push to source branch AND source branch is set for deletion
-
💬 Deletes source branch [?]-
❓ Tooltip: A user with write access to the source branch selected this option
-
-
🐛 If the MR can’t be merged, this message is not shown to users who have write access to the source branch but it’s still being shown to users who don’t have write access to the source branch.
-
- Fork merge pipeline warning — if source branch is from a fork AND merge results pipelines is enabled AND MR is open
-
💬 Fork project merge requests do not create merge request pipelines that validate a post merge result unless invoked by a project member. [?]
-
- Merge help message — If MR state is merging, has conflicts, is marked as draft, is can be merged, is checking status, has unresolved threads, has failing pipeline, has blocked pipeline, has failed auto-merge, or must be rebased:
- If source or target branch is missing:
-
💬 If the {source|target branch name} branch exists in your local repository, you can merge this merge request manually using the [command line] -
🐛 This message is never shown because themissingBranch
state comes before the states mentioned above.
-
- Else:
-
💬 You can merge this merge request manually using the [command line]-
🔗 Link to “Check out branch modal”
-
-
- If source or target branch is missing:
Screenshots
- Google Drive: https://drive.google.com/drive/folders/1xduONjCcYSsFm7HvVvdxyjF_qH5ty8R5?usp=sharing
- ZIP: Merge_widget_states_screenshots.zip
Resources
Edited by Pedro Moreira da Silva