glab-mr
Skill1 starsChanged 7 months agoMITView on GitHub
Create, view, manage, approve, and merge GitLab merge requests. Use when working with MRs: creating from branches/issues, reviewing, approving, adding comments, resolving discussion threads, checking out locally, viewing diffs, rebasing, merging, or managing state. Triggers on merge request, MR, pull request, PR, review, approve, merge, resolve thread.
- Commits and pushes
We split this skill into the rules it gives an agent
9 rules. 0 are common, 5 are distinctive, and 4 are very specific to this project.
0
Common
Most of the 5 edited versions we read keep these.
5
Distinctive
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 8
Create, view, and manage GitLab merge requests.
- Distinctive: line 123
Check if you're the author (can't self-approve in most configs)
- Distinctive: line 125
Ensure MR is not in draft state
- Very specific: line 128
Check .gitlab-ci.yml exists in branch
- Distinctive: line 129
Verify CI/CD is enabled for project
- Very specific: line 141
Use glab mr for <issue-id> to create MR linked to issue
- Very specific: line 146
Use glab mr create --auto-merge to request auto-merge up front, or glab mr merge --when-pipeline-succeeds on an existing MR
- Very specific: line 275
If GitLab rejects it with a line_code validation error, compute the diff anchor and retry with position[line_range][start/end][line_code].
- Distinctive: line 280
Only if that retry also fails should your broader review workflow fall back to a root MR note that clearly says inline anchoring failed …
“Common” is measured: kept by at least 6 in 10 of the 5 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
glab mr
Create, view, and manage GitLab merge requests.
Quick start
# Create MR from current branch
glab mr create --fill
# List my MRs
glab mr list --assignee=@me
# Review an MR
glab mr checkout 123
glab mr diff
glab mr approve
# Merge an MR
glab mr merge 123 --when-pipeline-succeeds --remove-source-branchCommon workflows
Creating MRs
From current branch:
glab mr create --fill --label bugfix --assignee @reviewer
# Create now, merge automatically when checks pass (v1.90.0+)
glab mr create --fill --auto-mergeFrom issue:
glab mr for 456 # Creates MR linked to issue #456Draft MR:
glab mr create --draft --title "WIP: Feature X"Review workflow
- List pending reviews:
glab mr list --reviewer=@me --state=opened - Checkout and test:
glab mr checkout 123 npm test - Leave feedback:
glab mr note 123 -m "Looks good, one question about the cache logic" # List discussion threads on the MR (v1.90.0+, experimental) glab mr note list 123 # Resolve a discussion by note/discussion ID (v1.90.0+, experimental) glab mr note resolve 3107030349 123 # Reopen a resolved discussion (v1.90.0+, experimental) glab mr note reopen 3107030349 123 # If you need to change thread state in v1.90.0, use the explicit subcommands glab mr note resolve <discussion-id> 123 glab mr note reopen <discussion-id> 123 - Approve:
glab mr approve 123
Automated review workflow:
For repetitive review tasks, use the automation script:
scripts/mr-review-workflow.sh 123
scripts/mr-review-workflow.sh 123 "pnpm test"This automatically: checks out → runs tests → posts result → approves if passed.
Merge strategies
Auto-merge when pipeline passes:
glab mr merge 123 --when-pipeline-succeeds --remove-source-branchSquash commits:
glab mr merge 123 --squashRebase before merge:
glab mr rebase 123
glab mr merge 123Troubleshooting
Merge conflicts:
- Checkout MR:
glab mr checkout 123 - Resolve conflicts manually in your editor
- Commit resolution:
git add . && git commit - Push:
git push
Cannot approve MR:
- Check if you're the author (can't self-approve in most configs)
- Verify permissions:
glab mr approvers 123 - Ensure MR is not in draft state
Pipeline required but not running:
- Check
.gitlab-ci.ymlexists in branch - Verify CI/CD is enabled for project
- Trigger manually:
glab ci run
"MR already exists" error:
- List existing MRs from branch:
glab mr list --source-branch <branch> - Close old MR if obsolete:
glab mr close <id> - Or update existing:
glab mr update <id> --title "New title"
Related Skills
Working with issues:
- See
glab-issuefor creating/managing issues - Use
glab mr for <issue-id>to create MR linked to issue - Script:
scripts/create-mr-from-issue.shautomates branch + MR creation
CI/CD integration:
- See
glab-cifor pipeline status before merging - Use
glab mr create --auto-mergeto request auto-merge up front, orglab mr merge --when-pipeline-succeedson an existing MR
Automation:
- Script:
scripts/mr-review-workflow.shfor automated review + test workflow
Posting Inline Comments on MR Diffs
The glab api --field Problem
glab api --field position[new_line]=N silently falls back to a general (non-inline) comment
when GitLab rejects the position data. This happens with:
- Entirely new files (
new_file: truein the diff) - Files with complex/encoded paths
- Any nested position field that doesn't survive form encoding
There is no error — GitLab just drops the position and creates a general discussion. You won't know
it failed unless you check the returned note's position field.
The Fix: Always Use JSON Body
Post inline comments via the REST API with a Content-Type: application/json body:
import json, urllib.request, urllib.parse, subprocess
# Get token from glab config
token = subprocess.run(
["glab", "config", "get", "token", "--host", "gitlab.com"],
capture_output=True, text=True
).stdout.strip()
project = urllib.parse.quote("mygroup/myproject", safe="")
mr_iid = 42
# Always fetch fresh SHAs — never use cached values
r = urllib.request.urlopen(urllib.request.Request(
f"https://gitlab.com/api/v4/projects/{project}/merge_requests/{mr_iid}/versions",
headers={"PRIVATE-TOKEN": token}
))
v = json.loads(r.read())[0]
payload = {
"body": "Your comment here",
"position": {
"base_sha": v["base_commit_sha"],
"start_sha": v["start_commit_sha"],
"head_sha": v["head_commit_sha"],
"position_type": "text",
"new_path": "src/utils/helpers.ts",
"new_line": 16,
"old_path": "src/utils/helpers.ts", # for renamed files, use the diff's actual old_path
"old_line": None # None = added line
}
}
req = urllib.request.Request(
f"https://gitlab.com/api/v4/projects/{project}/merge_requests/{mr_iid}/discussions",
data=json.dumps(payload).encode(),
headers={"PRIVATE-TOKEN": token, "Content-Type": "application/json"},
method="POST"
)
with urllib.request.urlopen(req) as resp:
result = json.loads(resp.read())
note = result["notes"][0]
is_inline = note.get("position") is not None # True = inline, False = fell back to general
print("inline:", is_inline, "| disc_id:", result["id"])Finding the Correct Line Number
Line numbers must point to an added line (+ prefix) in the diff — context lines and removed
lines will cause the position to be rejected:
import re
def get_new_line_number(diff_text, keyword):
"""Find the new_file line number of the first added line containing keyword."""
new_line = 0
for line in diff_text.split("\n"):
hunk = re.match(r"@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@", line)
if hunk:
new_line = int(hunk.group(1)) - 1
continue
if line.startswith("-") or line.startswith("\\"):
continue
new_line += 1
if line.startswith("+") and keyword in line:
return new_line
return None
# Usage
diffs = json.loads(...) # from /merge_requests/{iid}/diffs
for d in diffs:
if d["new_path"] == "src/utils/helpers.ts":
line = get_new_line_number(d["diff"], "safeParse")
print("line:", line)Reusable Script
For scripted or automated MR reviews, use the bundled helper:
# Single comment
python3 scripts/post-inline-comment.py \
--project "mygroup/myproject" \
--mr 42 \
--file "src/utils/helpers.ts" \
--line 16 \
--body "This returns the wrapper object — use .data instead."
# Batch from JSON file
python3 scripts/post-inline-comment.py \
--project "mygroup/myproject" \
--mr 42 \
--batch comments.jsonBatch file format:
[
{ "file": "src/utils/helpers.ts", "line": 16, "body": "Comment 1" },
{ "file": "src/routes/+page.svelte", "line": 58, "body": "Comment 2" }
]The script auto-reads your token from glab config, fetches fresh SHAs and diffs, and uses a two-step anchoring strategy:
- Try the normal
position[new_line]inline payload first. - If GitLab rejects it with a
line_codevalidation error, compute the diff anchor and retry withposition[line_range][start/end][line_code].
That retry path is the preferred recovery for failures like:
400 Bad request - Note {:line_code=>["can't be blank", "must be a valid line code"]}
Only if that retry also fails should your broader review workflow fall back to a root MR note that clearly says inline anchoring failed while preserving the exact finding text and reviewer identity.
Filtering discussion threads by resolution (v1.88.0+)
# Show only unresolved discussion threads on an MR
glab mr view 123 --unresolved
# Show only resolved threads
glab mr view 123 --resolvedUseful for quickly checking which review threads still need attention before merging.
v1.87.0 Changes: New glab mr list Flags
The following flags were added to glab mr list in v1.87.0:
# Filter by author
glab mr list --author <username>
# Filter by source or target branch
glab mr list --source-branch feature/my-branch
glab mr list --target-branch main
# Filter by draft status
glab mr list --draft
glab mr list --not-draft
# Filter by label or exclude label
glab mr list --label bugfix
glab mr list --not-label wip
# Order and sort
glab mr list --order updated_at --sort desc
glab mr list --order merged_at --sort asc
# Date range filtering
glab mr list --created-after 2026-01-01
glab mr list --created-before 2026-03-01
# Search in title/description
glab mr list --search "login fix"
# Full flag reference (all available flags)
glab mr list \
--assignee @me \
--author vince \
--reviewer @me \
--label bugfix \
--not-label wip \
--source-branch feature/x \
--target-branch main \
--milestone "v2.0" \
--draft \
--state opened \
--order updated_at \
--sort desc \
--search "auth" \
--created-after 2026-01-01v1.90.0 Updates
glab mr createadds--auto-mergeto set merge-when-ready during MR creationglab mr noteaddslist,resolve, andreopensubcommands for discussion management (EXPERIMENTAL)- For discussion state changes in v1.90.0, prefer
glab mr note resolve/glab mr note reopen; do not imply--resolve/--unresolvecan be combined with-m
v1.89.0 Updates
v1.89.0+:
glab mr approverssupports--output json/-F jsonfor structured output, ideal for agent automation.
# View MR approvers with JSON output (v1.89.0+)
glab mr approvers 123 --output json
glab mr approvers 123 -F jsonv1.88.0 Changes
glab mr note: Added--resolve <discussion-id>and--unresolve <discussion-id>flags for discussion state changes; in v1.90.0 docs should prefer the explicitnote resolve/note reopensubcommands for user-facing guidanceglab mr view: Added--resolvedand--unresolvedflags to filter displayed discussion threads by resolution status
Command reference
For complete command documentation and all flags, see references/commands.md.
Available commands:
approve- Approve merge requestscheckout- Check out an MR locallyclose- Close merge requestcreate- Create new MRdelete- Delete merge requestdiff- View changes in MRfor- Create MR for an issuelist- List merge requestsmerge- Merge/accept MRnote- Add comment to MR; includeslist,resolve, andreopensubcommands in v1.90.0rebase- Rebase source branchreopen- Reopen merge requestrevoke- Revoke approvalsubscribe/unsubscribe- Manage notificationstodo- Add to-do itemupdate- Update MR metadataview- Display MR details
Other versions5 projects use a version of this.
Word for word · 0
None found.
Edited · 2
- vince-winkintel/gitlab-cli-skills★ 4916% same
- cormacc/dotagents★ 156% same
Wrote their own version · 3
- arfar-x/agent-skills★ 13same name
- akhy/agent-skills★ 1same name
- BolasLien/skills★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository52 other files it gives its agents.
- gh-cliSkill
- glab-aliasSkill
- glab-apiSkill
- glab-attestationSkill
- glab-authSkill
- glab-changelogSkill
- glab-check-updateSkill
- glab-ciSkill
- glab-clusterSkill
- glab-completionSkill
- glab-configSkill
- glab-deploy-keySkill
- glab-duoSkill
- glab-gpg-keySkill
- glab-helpSkill
- glab-incidentSkill
- glab-issueSkill
- glab-iterationSkill
- glab-jobSkill
- glab-labelSkill
- glab-mcpSkill
- glab-milestoneSkill
- glab-opentofuSkill
- glab-quick-actionsSkill
- glab-releaseSkill
- glab-repoSkill
- glab-runner-controllerSkill
- glab-runnerSkill
- glab-scheduleSkill
- glab-securefileSkill
- glab-snippetSkill
- glab-ssh-keySkill
- glab-stackSkill
- glab-todoSkill
- glab-tokenSkill
- glab-userSkill
- glab-variableSkill
- glab-versionSkill
- glab-workitemsSkill
- gitlab-cli-skillsSkill
- ui-color-palette-audit-paletteSkill
- ui-color-palette-build-color-systemSkill
- ui-color-palette-figmaSkill
- ui-color-palette-framerSkill
- ui-color-palette-generate-codeSkill
- ui-color-palette-generate-semantic-codeSkill
- ui-color-palette-generate-source-colorsSkill
- ui-color-palette-helpSkill
- ui-color-palette-manage-palettesSkill
- ui-color-palette-penpotSkill
- ui-color-palette-scale-paletteSkill
- ui-color-palette-sketchSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

