Merge Requests, Drafts, Review Threads, Suggestions, and Change Collaboration: Concepts, Architecture, and Mental Model
Build a beginner-first mental model of GitLab merge requests as governed change objects that join Git refs, diff identity, review state, discussions, pipelines, issue links, and merge intent.
Learning objectives
- Explain a merge request as hosted state around ordinary source/target Git refs rather than as a new Git object type.
- Relate source SHA, target SHA, diff, commits, pipeline evidence, review state, discussions, approvals, and mergeability without collapsing them into one status.
- Distinguish draft/ready state, author, assignee, reviewer, participant, and approver responsibilities.
- Explain resolvable review threads and suggestions, including the commit/authorship effect of applying a suggestion.
- Model same-project and fork merge requests with explicit project, runner, variable, and credential trust boundaries.
glab mr command family are documented for
Free/Premium/Ultimate on GitLab.com, Self-Managed, and Dedicated. On
GitLab Free, eligible users can approve an MR, but
approvals are optional and do not enforce a merge gate;
required approval rules are Premium/Ultimate. Draft
MRs cannot merge until marked ready, but by default they run the same
MR pipelines as ready MRs. Current fork-pipeline behavior and
protected-resource rules are version-sensitive, so production policy
must be checked against the deployed GitLab version.
1. Why a branch alone is not enough for governed delivery
Git already gives you commits, branches, remotes, and merge
operations. Those mechanics answer “what bytes changed?” and “what
history can be integrated?” They do not, by themselves, answer who
reviewed the change, why it exists, whether CI evaluated the right
revision, whether a discussion remains unresolved, whether a linked
issue should close, or whether a maintainer intends the change for
main versus a release branch.
A GitLab merge request (MR) is the hosted coordination object that surrounds those Git refs with review, policy, CI, discussion, and delivery state. The underlying commits remain normal Git commits. The MR is the control plane that says: “compare this source state with that target state, evaluate it, discuss it, and—only if policy permits—integrate it.”
2. Mental model: one proposed change, several independent states
flowchart TD
DEV[Developer worktree] -->|commit + push| SRC[Source branch / source SHA]
TGT[Target branch / target SHA] --> DIFF[MR comparison]
SRC --> DIFF
DIFF --> MR[Merge request metadata]
MR --> REV[Review threads / suggestions]
MR --> PIPE[Pipeline evidence]
MR --> LINK[Linked issue / intent]
REV --> READY{Ready and mergeable?}
PIPE --> READY
LINK --> READY
READY -->|merge| TGT2[Updated target branch]
READY -->|close| CLOSED[No target change]
FORK[Fork source project] -.different trust boundary.-> SRC
The arrows matter. A push changes the source branch SHA first; GitLab then recalculates the MR diff and related mergeability state. A review comment does not change Git bytes. Applying a suggestion does. A successful pipeline is evidence about a particular ref/SHA, not permission to merge by itself. Closing an MR changes hosted MR state but does not integrate its commits into the target branch.
3. The merge request object: what GitLab stores around Git
| Element | What it represents | Where it lives | Beginner mistake |
|---|---|---|---|
| Source branch | Proposed commits; may be in same project or fork | Git ref in source project | Treating “MR !12” as if it were itself a branch |
| Target branch | Destination and release intent | Git ref in target project |
Reviewing code for main while MR actually
targets release/old
|
| Diff / diff refs | Comparison derived from source and target histories | GitLab-hosted MR metadata backed by Git commits | Assuming a cached/web diff is the only evidence worth inspecting |
| MR description | Intent, testing notes, issue links, rollout context | GitLab database | Putting secrets or confidential incident data in a public MR |
| Pipeline status | Execution evidence for a pipeline source/ref | GitLab CI/CD | Assuming green means it tested the exact post-merge state |
| Discussion | Review conversation; some threads are resolvable | GitLab collaboration state | Resolving the UI thread without fixing the underlying code |
| Approval | Reviewer approval state | GitLab governance state | Assuming Free approval is automatically an enforced gate |
| Merge state | Open/draft/ready/merged/closed + mergeability | GitLab application state | Treating “ready” as proof that every organization policy is satisfied |
4. Draft, ready, assignee, reviewer, and approval are different concepts
Draft means the author is explicitly declaring that the MR should not merge yet. Current GitLab prevents a draft MR from merging even if other checks pass. Marking it ready removes that block and notifies relevant participants/watchers; it does not create approval, fix CI, or guarantee mergeability.
An assignee owns progress on the MR. A reviewer is asked to review. A participant is anyone who has interacted. An approver records approval when eligible. On Free, approvals can be recorded but are not a required merge gate. Required approval rules and richer approval governance belong to Premium/Ultimate and are covered deeply in Chapter 08.
5. Review threads and suggestions: conversation can become a commit
A plain MR comment records conversation. A diff discussion anchors the conversation to a location in a particular diff. A resolvable thread carries an explicit resolved/unresolved state. That state is useful evidence, but it is not proof that the code changed: a user can resolve a thread without modifying the source branch.
A suggestion is stronger. A reviewer proposes concrete replacement text in a diff thread. When an authorized user applies it, GitLab creates a new commit on the MR source branch and marks the suggestion applied; the thread is resolved as part of that operation. Current GitLab documents the resulting commit as authored by the user who suggested the change. That makes suggestion authorship an audit concern, not just a UI convenience.
6. MR refs: hosted refs around the branch state
GitLab exposes a merge-request head ref such as
refs/merge-requests/42/head. It points at the current
source-side commit GitLab associates with the MR and allows tools
such as glab mr checkout to inspect the proposed
revision without manually constructing a local branch name. GitLab
can also maintain a merge ref representing what a regular merge
would produce when the MR is mergeable.
These refs help CI, local review, and API workflows, but they are not substitutes for the canonical branch and commit identities. Treat them as GitLab-managed integration refs with their own lifecycle.
# Read-only examples after MR_IID is known.
glab mr view "$MR_IID" --comments
git fetch origin "merge-requests/$MR_IID/head:mr-$MR_IID-review"
git show --no-patch --decorate "mr-$MR_IID-review"
# Or let glab perform the checkout safely in a clean worktree.
glab mr checkout "$MR_IID" --branch "mr-$MR_IID-review"
7. Fork merge requests change the trust boundary
In a same-project MR, source and target branches live in one project. In a fork MR, the source branch lives in a different project, often controlled by an external contributor. GitLab therefore has to distinguish code being reviewed from resources belonging to the target project.
Current GitLab behavior is intentionally conservative: a fork MR pipeline normally runs in the fork and uses the fork project’s CI configuration/resources/variables. A sufficiently privileged target-project member can choose to run a pipeline in the parent project, but that executes the fork branch’s CI configuration with parent-project settings/resources and the triggering member’s authority. That is a privilege boundary, not a convenience button.
Current GitLab also restricts protected-variable/protected-runner access for MR pipelines: fork MRs cannot access those protected resources through the same-project protected-branch path. The exact rules are version-sensitive and should be re-verified whenever CI policy changes.
8. Read-only inspection before review
Use the UI for human context, but capture structured state too. The REST response can prove the source/target names, source SHA, target/diff refs, draft flag, pipeline identity, and detailed merge status.
REPO="GROUP/PROJECT"
PROJECT_ID="123456" # disposable project ID
MR_IID="7" # synthetic example
glab auth status
glab mr view "$MR_IID" -R "$REPO" --comments
glab api "projects/$PROJECT_ID/merge_requests/$MR_IID" --jq '{iid,title,state,draft,source_project_id,target_project_id,source_branch,target_branch,sha,diff_refs,detailed_merge_status,web_url}'
glab api "projects/$PROJECT_ID/merge_requests/$MR_IID/discussions" --paginate --jq '.[] | {id,notes:[.notes[] | {id,resolvable,resolved,body}]}'
If detailed_merge_status is temporarily
checking, do not invent a conclusion. GitLab calculates
some mergeability state asynchronously; re-read the resource after
the check settles.
9. DevOps connection: the MR is a convergence point, not the source of truth for everything
Production delivery uses the MR as a convergence point: Git commits provide source identity; reviewers provide human judgment; pipelines provide execution evidence; issue links provide intent; protected branches and approvals provide governance; releases later provide deployment identity. The MR coordinates these planes but does not replace any one of them.
That distinction prevents a common failure: “the MR page looked green, so it was safe.” A reliable operator asks: green for which SHA, in which project, with which runner/variables, targeting which branch, with what unresolved discussion, and under which approval/protection policy?
Knowledge check
A reviewer resolves a thread, but the source-branch SHA is unchanged. What does that prove?
Only the discussion state changed. It does not prove the code concern was fixed; inspect the source diff and commit history independently.
Does marking a draft MR ready approve it?
No. Ready removes the draft merge block and signals review readiness. Approval is separate state, and required approval enforcement depends on tier/policy.
Why is a fork MR more than “the same MR from another branch”?
Its source project can be controlled by another trust domain, so runners, variables, CI configuration, membership, and resource access must be reasoned about separately from the target project.
What is refs/merge-requests/7/head?
A GitLab-managed ref for the MR head revision. It helps checkout/CI workflows but is not a new Git object type or a replacement for source branch/SHA evidence.
On GitLab Free, does one recorded approval automatically block merging until approval exists?
No. Free approvals are optional. Required approval rules are Premium/Ultimate governance features.
Summary
A merge request layers intent, review, CI, discussion, and merge state around ordinary Git source/target refs. Draft, ready, reviewer, approval, discussion resolution, pipeline status, and mergeability are independent signals. Suggestions can create commits; fork workflows cross project trust boundaries; MR refs aid inspection but do not replace canonical commit identity. The next lesson turns this model into a reproducible Free-compatible workflow.
Official references
- GitLab Docs — Merge requests
- GitLab Docs — Create merge requests
- GitLab Docs — Draft merge requests
- GitLab Docs — Merge request reviews
- GitLab Docs — Suggest changes
- GitLab Docs — Merge request workflows
- GitLab Docs — Merge request pipelines
- GitLab Docs — Changes in merge requests
- GitLab Docs — Troubleshooting merge requests
- GitLab Docs — Merge request approvals
- GitLab Docs — Default branch
- GitLab Docs — Merge requests API
- GitLab Docs — Discussions API
- GitLab Docs — Suggest Changes API
- GitLab Docs — glab mr
- GitLab Docs — glab mr create
- GitLab Docs — glab mr update
- GitLab Docs — glab mr view
- GitLab Docs — glab mr checkout
- GitLab Docs — glab mr merge
- GitLab Docs — REST API pagination
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this
address.