Checkpoint Lab — Merge Requests, Drafts, Review Threads, Suggestions, and Change Collaboration
Execute a complete disposable issue-to-branch-to-draft-MR-to-review-to-merge workflow, predict commit identity and issue state, preserve independent evidence, diagnose one stale discussion, and clean up safely.
Learning objectives
- Run one complete Free-compatible issue → branch → draft MR → review suggestion → ready → merge workflow in a disposable project.
- Predict source/target commit identity and linked-issue state before each consequential transition.
- Use UI, local Git, glab, and REST as independent evidence surfaces rather than relying on one green widget.
- Diagnose one deliberately stale/unresolved review condition before merge and repair it without bypassing policy.
- Produce a compact evidence packet and perform targeted cleanup without deleting the project or rewriting history.
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. Checkpoint mission and preflight
Your goal is to deliver one tiny documentation change with a traceable reason and a reviewable source identity. The lab remains deliberately small so you can focus on causality rather than application complexity.
- Project: disposable GitLab.com Free project you own.
-
Local tools: Git + current
glab;sha256sumis optional but useful for evidence integrity. - Role: sufficient to create branch/MR and merge into the disposable target under its existing protection rules.
- Second reviewer: optional existing test collaborator. Do not grant new access solely for this exercise.
- No paid dependencies: required approval rules, Code Owners, merge trains, privileged runners, protected variables, Dedicated administration, Kubernetes, cloud, and AI are not required.
2. Predict the state transitions before touching GitLab
flowchart TD
I[Open synthetic issue] --> B[Feature branch at base SHA]
B --> C[New commit / source SHA]
C --> D[Draft MR: target unchanged]
D --> R[Review thread + suggestion]
R --> S[Apply suggestion: new source SHA]
S --> U[Ready state]
U --> E{Evidence current?}
E -->|No| FIX[Re-review / repair]
FIX --> E
E -->|Yes| M[Merge exact reviewed SHA]
M --> T[Target branch changes]
M --> Q[Issue closes if default-branch closing semantics apply]
T --> X[Cleanup source branch + archive evidence]
Q --> X
Write down at least two predictions now: (1) draft-MR creation will not move the target branch; (2) applying the suggestion will move the source branch; (3) merge will move the target branch; (4) the linked issue should close only if the closing pattern reaches the default branch under current project settings.
3. Set up evidence directory and capture baseline
REPO="GROUP/ch07-checkpoint"
PROJECT_ID="123456"
DEFAULT="main" # verify from project; change if needed
BRANCH="ch07-checkpoint-change"
mkdir -p ch07-checkpoint
glab auth status
glab repo view -R "$REPO" --output json --jq '{path_with_namespace,visibility,default_branch}' | tee ch07-checkpoint/project.json
git fetch origin --prune
git status --short
BASE_SHA="$(git rev-parse "origin/$DEFAULT")"
printf 'base_sha=%s
' "$BASE_SHA" | tee ch07-checkpoint/01-base.txt
4. Create the traceable work item
Create a synthetic issue titled
CH07 checkpoint: document probe behavior. Record the
actual IID in ISSUE_IID. The issue is the problem
statement; it is not the code change.
glab issue create -R "$REPO" --title "CH07 checkpoint: document probe behavior" --description "Synthetic Chapter 07 checkpoint issue. No production data." --yes
ISSUE_IID="21" # replace with actual IID
glab issue view "$ISSUE_IID" -R "$REPO" | tee ch07-checkpoint/02-issue.txt
5. Create the branch and first commit
git switch -c "$BRANCH" "origin/$DEFAULT"
printf '
## Probe behavior
Synthetic checkpoint text.
' >> README.md
git add README.md
git commit -m "docs: add CH07 checkpoint probe note"
git push -u origin "$BRANCH"
FIRST_SOURCE_SHA="$(git rev-parse HEAD)"
printf 'first_source_sha=%s
' "$FIRST_SOURCE_SHA" | tee ch07-checkpoint/03-source-first.txt
Verify origin/$DEFAULT is still $BASE_SHA.
If not, stop and determine what else updated the branch; do not
attribute an unrelated push to your feature branch.
6. Create a draft MR with linked intent
glab mr create -R "$REPO" --source-branch "$BRANCH" --target-branch "$DEFAULT" --title "CH07 checkpoint: probe documentation" --description "Closes #$ISSUE_IID
Synthetic checkpoint. Review the exact source SHA before merge." --draft --yes
# Find and record the actual IID from this source branch.
glab mr list -R "$REPO" --source-branch "$BRANCH" --output json | tee ch07-checkpoint/04-mr-list.json
MR_IID="9" # replace with actual IID
glab api "projects/$PROJECT_ID/merge_requests/$MR_IID" --jq '{iid,state,draft,source_branch,target_branch,sha,diff_refs,detailed_merge_status,head_pipeline}' | tee ch07-checkpoint/05-mr-draft.json
Verification: target branch remains at the baseline SHA; MR is draft; MR SHA equals the remote feature branch; no claim is made about CI if no pipeline exists.
7. Create a deliberate review concern and suggestion
In the Changes view, add a resolvable diff thread: “The heading should make the training-only nature explicit.” Capture the unresolved discussion through the REST API.
glab api "projects/$PROJECT_ID/merge_requests/$MR_IID/discussions" --paginate --jq '.[] | {id,notes:[.notes[] | {id,type,resolvable,resolved,body}]}' | tee ch07-checkpoint/06-discussions-unresolved.json
Now add a suggestion that changes the heading to
## Training-only probe behavior. Before applying it,
record the source SHA. Apply the suggestion in the UI, then fetch
and prove the new commit.
PRE_SUGGEST="$(glab api "projects/$PROJECT_ID/merge_requests/$MR_IID" --jq '.sha')"
printf 'pre_suggest=%s
' "$PRE_SUGGEST" | tee ch07-checkpoint/07-pre-suggest.txt
# Apply the synthetic suggestion in the GitLab UI, then:
git fetch origin "$BRANCH"
POST_SUGGEST="$(git rev-parse "origin/$BRANCH")"
printf 'post_suggest=%s
' "$POST_SUGGEST" | tee ch07-checkpoint/08-post-suggest.txt
test "$PRE_SUGGEST" != "$POST_SUGGEST" || { echo "Expected a new suggestion commit"; exit 1; }
git show --format=fuller --stat "$POST_SUGGEST" | tee ch07-checkpoint/09-suggestion-commit.txt
8. Diagnose one deliberately stale discussion condition
Create a second review thread that says “Verify the sentence ends with a period.” Then deliberately leave it unresolved even after the text is already correct. This is a stale review signal: code state and discussion state disagree.
Inspect the discussion and source diff. If the code is objectively correct, reply with the evidence and resolve the thread. Do not make a meaningless code edit just to produce a commit.
CURRENT_SHA="$(glab api "projects/$PROJECT_ID/merge_requests/$MR_IID" --jq '.sha')"
glab mr diff "$MR_IID" -R "$REPO" | tee ch07-checkpoint/10-current-diff.txt
glab mr view "$MR_IID" -R "$REPO" --comments --unresolved | tee ch07-checkpoint/11-unresolved-view.txt
glab api "projects/$PROJECT_ID/merge_requests/$MR_IID/discussions" --paginate | tee ch07-checkpoint/12-discussions-before-resolution.json
Resolve only after the evidence shows the concern is satisfied. Then record the discussion state again. The source SHA should remain unchanged if this was truly a stale discussion rather than a code defect.
9. Mark ready and prove the reviewed head
glab mr update "$MR_IID" -R "$REPO" --ready --yes
REVIEWED_SHA="$(glab api "projects/$PROJECT_ID/merge_requests/$MR_IID" --jq '.sha')"
glab api "projects/$PROJECT_ID/merge_requests/$MR_IID" --jq '{iid,draft,sha,detailed_merge_status,source_branch,target_branch,reviewers,head_pipeline}' | tee ch07-checkpoint/13-ready.json
# Independent remote proof.
REMOTE_SOURCE_SHA="$(git ls-remote origin "refs/heads/$BRANCH" | awk '{print $1}')"
test "$REVIEWED_SHA" = "$REMOTE_SOURCE_SHA" && echo "MR head equals remote source head"
10. Final predictions before merge
- Target SHA: must change if the MR actually merges.
- Source SHA: must remain the exact reviewed SHA at the moment you authorize merge.
- MR state: becomes merged, not merely closed.
- Issue: should close if the closing reference reaches the default branch and auto-closing is enabled.
- Source branch: should be removed if you choose the remove-source-branch option.
TARGET_BEFORE="$(git ls-remote origin "refs/heads/$DEFAULT" | awk '{print $1}')"
printf 'reviewed_sha=%s
target_before=%s
' "$REVIEWED_SHA" "$TARGET_BEFORE" | tee ch07-checkpoint/14-final-predictions.txt
11. Merge the exact reviewed SHA and verify independently
glab mr merge "$MR_IID" -R "$REPO" --sha "$REVIEWED_SHA" --remove-source-branch --auto-merge=false --yes
git fetch origin --prune
TARGET_AFTER="$(git rev-parse "origin/$DEFAULT")"
printf 'target_after=%s
' "$TARGET_AFTER" | tee ch07-checkpoint/15-target-after.txt
glab api "projects/$PROJECT_ID/merge_requests/$MR_IID" --jq '{iid,state,merged_at,sha,merge_commit_sha,squash_commit_sha,source_branch,target_branch}' | tee ch07-checkpoint/16-mr-merged.json
glab issue view "$ISSUE_IID" -R "$REPO" | tee ch07-checkpoint/17-issue-after.txt
git log --oneline --decorate -5 "origin/$DEFAULT" | tee ch07-checkpoint/18-target-log.txt
If the merge command refuses because --sha no longer
matches, that is a successful safety control. Do not bypass it;
inspect the new source commit and repeat review evidence.
12. Build the evidence packet
glab api "projects/$PROJECT_ID/merge_requests/$MR_IID/discussions" --paginate > ch07-checkpoint/19-discussions-final.json
glab api "projects/$PROJECT_ID/merge_requests/$MR_IID/commits" --paginate > ch07-checkpoint/20-commits-final.json
sha256sum ch07-checkpoint/* > ch07-checkpoint/SHA256SUMS.txt
cat ch07-checkpoint/SHA256SUMS.txt
The hashes prove whether your local evidence packet changes after capture; they do not make the API response “trusted” by themselves. Your claims are strongest when multiple independent surfaces agree on the same source/target identities.
13. Cleanup and rollback boundaries
The merge itself is intentionally retained as training history. Cleanup only disposable transient resources:
- Return the local worktree to the default branch and delete the local feature branch.
-
Verify the remote source branch is gone if
--remove-source-branchwas accepted. - Keep the closed issue/MR and evidence packet if useful for Chapter 08; otherwise archive the evidence outside any public repository.
- Do not delete the whole project, rewrite the merged history, alter protected-branch policy, or create a bypass to “undo” the lab.
git switch "$DEFAULT"
git branch -D "$BRANCH" 2>/dev/null || true
git remote prune origin
git ls-remote --heads origin "$BRANCH"
git status --short
14. What Chapter 07 adds to the production operating model
The operating model now has a governed change-convergence layer. Chapters 01–06 established platform boundaries, credentials, project defaults, namespace access, planning, and collaboration surfaces. Chapter 07 ties a proposed source revision to a target branch, review evidence, CI state, discussions, and delivery intent.
Chapter 08 will turn this collaborative process into enforceable governance: approval rules, CODEOWNERS, protected branches/tags, push rules, and merge constraints. The distinction matters: Chapter 07 teaches how people collaborate around a change; Chapter 08 teaches which controls may prevent an unsafe change from completing.
Knowledge check
The merge fails because the source SHA changed after you
captured REVIEWED_SHA. What should you do?
Treat the refusal as protection. Inspect the new commit/diff, refresh review/CI evidence, update the reviewed SHA, and only then reconsider merge.
You resolve the stale punctuation thread and the MR head SHA stays the same. Is that automatically suspicious?
No. In this exercise the code was already correct; only discussion state needed repair. The unchanged SHA is evidence that no unnecessary source mutation occurred.
The issue remains open after the MR merges. Which facts should you inspect before manually closing it?
The actual MR target, project default branch, closing keyword/link, auto-closing configuration, and whether the merge reached the default branch.
Why keep both REST MR JSON and local
git log evidence?
They prove different planes: GitLab hosted MR state versus repository commit/ref state. Agreement provides stronger causal evidence.
What chapter comes next, and what new problem does it solve?
Chapter 08 adds enforceable merge governance through approvals, CODEOWNERS, protected refs, push rules, and related controls.
Which paid feature was intentionally not required in this checkpoint?
Required approval rules (and other Premium/Ultimate governance such as deeper Code Owner/approval enforcement) were not required; the entire checkpoint remains Free-compatible.
Checkpoint summary
You completed an end-to-end GitLab change with explicit source/target identity, draft state, linked work, review thread, applied suggestion, stale-discussion diagnosis, ready transition, exact-SHA merge guard, default-branch verification, linked-issue inspection, evidence hashing, and targeted cleanup. The workflow is now ready to receive Chapter 08’s enforceable approval and protected-ref governance.
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.