关于 glab-mr
用于创建、审查和管理合并请求的 GitLab CLI 技能,涵盖分支与讨论操作、变更状态时的安全处理,以及自动化审查工作流。
主要功能
- 01创建和更新合并请求
- 02检出并检查变更
- 03管理审查评论和讨论串
- 04批准并合并请求
- 05自动执行审查与测试步骤
适用场景
- 01从分支或议题创建 MR
- 02审查变更并发布串联反馈
- 03流水线检查通过后合并
- 04运行测试并提交审查结果
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ vince-winkintel/ gitlab-cli-skills --skill glab-mr安装后在 Claude Code 中输入/glab-mr确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/commands.mdscripts/create-mr-from-issue.shmr-review-workflow.shpost-inline-comment.py详细介绍
glab mr
创建、查看和管理 GitLab 合并请求。
变基完成和议题分支
mr rebase 和 mr merge --rebase 会等待排队的服务端变基明确完成,而不会将初始的 rebase_in_progress=false 视为成功。轮询最多进行 300 次,间隔为一秒,并可响应取消操作。变基出错或超时会停止合并;经批准重试前,请先确认服务端状态。--sha 和 --rebase 不能同时使用,因为变基会改变头 SHA;--squash 和 --rebase 也不能同时使用。这些命令会修改分支/合并请求,执行前必须获得对确切目标的批准。
mr for 和 mr create --related-issue 仅在遇到 HTTP 400 名称/层级冲突时重试创建分支,并依次尝试后缀 -1 到 -100。遇到身份验证、权限、无效引用、网络故障及其他无关错误时会立即停止。请先诊断原始错误,不要反复创建分支,也不要对所有失败一概重试。请先确认议题、项目、基础分支和预期写入操作。
在另一个仓库中解决或重新打开讨论
使用 --repo 时,mr note resolve 和 mr note reopen 要求先指定合并请求,再指定讨论标识符:
glab mr note resolve 123 abc12345 --repo group/project
glab mr note reopen 123 abc12345 --repo group/project
讨论可以用完整 ID、至少 8 个字符的唯一前缀或数字形式的备注 ID 指定。不使用 --repo 时,省略合并请求会默认使用当前分支。二进制文件的用法说明中,操作数的顺序列得不一致;请遵循其示例和实现:先指定合并请求,再指定讨论。更改讨论状态前,请先确认目标。
检出、创建和筛选
glab mr checkout 123 --worktree ../review-mr-123 会获取并在单独的工作树中检出该合并请求。重新使用该路径会更新现有工作树。一个分支只能在一个工作树中检出;需要使用不同的本地名称时,请选择 --branch。请仔细检查关于分歧/重置的提示:工作树隔离并不意味着可以丢弃提交或本地更改。通过匹配的远程仓库获取时,会创建跟踪引用。
mr create --fill 会根据提交生成标题/描述;除非明确设置了 --push,否则默认会推送。使用 glab mr create --fill --push=false 可禁止推送;这仍会创建合并请求,并非试运行。请确保源分支已存在于远程仓库。创建草稿时不会额外添加第二个 Draft: 前缀。
glab mr update feature-branch --state opened --ready 会将分支查找范围限制为已打开的合并请求。可接受的状态包括 opened、closed、merged、locked 和 any(默认值);ID 和 URL 不受此筛选条件影响。--state 本身不会更改合并请求状态。
如果列表筛选条件恰好指定一个指派人且没有审阅者,或恰好指定一个审阅者且没有指派人,则会保留服务端排序。不要推断组合多个用户的结果也具有相同的排序保证。mr view 会显示可用的易读已耗时/预估耗时信息;机器处理时请使用 JSON。
模板选择
对于 create --template,不带路径的名称(可选带 .md)会在仓库的 .gitlab/merge_request_templates/ 目录下解析。绝对路径或包含路径分隔符的路径会直接读取;相对路径相对于当前目录,且支持 ~/。要使用当前目录中的文件,请使用 ./template.md,不要使用不带路径的模板名称。模板目录不存在时表示没有模板;其他目录列表错误会显示出来,重试前应先修复。发布前请阅读并批准文件内容;--description-file 仍不能与 --template 同时使用。
快速入门
# Create MR from current branch
glab mr create --fill
# Create or update with a multi-line description from a file
glab mr create --title "Fix login bug" --description-file description.md
glab mr update 123 --description-file description.md
# Attach local files to a description
glab mr create --title "Fix login bug" --description "Before and after:" \
--attach ./before.png --attach ./after.png
glab mr update 123 --attach ./latest.png
# 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-branch
自动化工具要使用补丁时,请使用 glab mr diff --raw。常规渲染后的差异面向人类阅读;--raw 会返回未经修改的 Git 补丁,并使用标准统一差异头。
常见工作流
创建 MR
从当前分支创建:
glab mr create --fill --label bugfix --assignee @reviewer
# Create now, merge automatically when checks pass
glab mr create --fill --auto-merge
# Start from an MR template file when your project uses one
glab mr create --fill --template .gitlab/merge_request_templates/default.md
对于一次性的多行描述,使用 --description-file <path>,或使用 --description-file - 从标准输入读取。它不能与 --description 同时使用;创建时,也不能与 --template 同时使用。若文件内容恰好为 -,则会被拒绝,因为 --description - 表示“打开编辑器”。
使用实验性的 --attach <path> 可重复上传文件,并将 GitLab 提供的 Markdown 引用追加到描述中。--attach - 会从标准输入读取一个文件,且不能与 --description-file - 共用标准输入。更新时,除非提供替换描述,否则附件会追加到现有描述中。对于 fork merge request,mr create 会将附件上传到目标项目,以便引用在该项目中生效。
在非交互环境中,只要显式指定 --title 即可;glab 可以创建描述为空的 MR,而不需要 TTY 或 --description。交互式终端仍会提示填写缺失的描述或模板。为实现确定性的自动化,请传入 --yes,并显式指定任何源、目标或仓库选择参数。
GLAB_NO_PROMPT=1 glab mr create \
--title "Fix login timeout" \
--source-branch fix/login-timeout \
--target-branch main \
--yes
没有本地 Git 检出时:
只要通过标志提供所有依赖远程的信息,glab mr create 就可以在 Git 仓库之外创建 MR。源分支必须已存在于所选源项目中。不要使用 --push、--fill 或 --template,因为这些选项需要本地仓库状态。
glab mr create \
--repo group/project \
--source-branch feature-branch \
--target-branch main \
--title "Add feature" \
--description "Details..." \
--yes
# Fork source into an upstream target
glab mr create \
--repo upstream/project \
--head your-namespace/project \
--source-branch feature-branch \
--target-branch main \
--title "Add feature" \
--description "Details..." \
--yes
从议题创建:
glab mr for 456 # Creates MR linked to issue #456
草稿 MR:
glab mr create --draft --title "WIP: Feature X"
审查工作流
-
列出待处理的审查:
glab mr list --reviewer=@me --state=opened -
检出并测试:
glab mr checkout 123 npm test -
留下反馈:
# Forward command surface for new MR comments/discussions glab mr note create 123 -m "Looks good, one question about the cache logic" # Automation/status update that should not create a resolvable thread glab mr note create 123 -m "Build status: green" --resolvable=false # Reply inside an existing discussion thread glab mr note create 123 --reply abc12345 -m "Good catch — updated" # Internal note visible only to project members glab mr note create 123 --internal -m "Rotating the leaked token now." # Native diff comments on the latest MR version glab mr note create 123 --file src/cache.ts --line 42 -m "Please extract this branch" glab mr note create 123 --file src/cache.ts --old-line 17 -m "Why was this removed?" # Stage comments in a private pending review, then publish them together glab mr note draft create 123 --file src/cache.ts --line 42 -m "Please extract this branch" glab mr note draft list 123 --output json glab mr note draft publish 123 --reviewer-state requested_changes --yes # Attach evidence to a new or existing note glab mr note create 123 -m "Rendered result" --attach ./result.png glab mr note update 123 456789 --attach ./updated.png # List discussion threads and expose note/discussion IDs (experimental) glab mr note list 123 glab mr note list 123 --state unresolved --type diff glab mr note list 123 --output json # Resolve or reopen a discussion by note/discussion ID (experimental) glab mr note resolve 123 3107030349 glab mr note reopen 123 3107030349对于
glab mr note update,注释 ID 始终是最后一个位置参数。帮助信息会先显示必需参数,再显示可选参数,但该命令会将最后一个参数解析为<note-id>;指定 MR 时,请使用glab mr note update <mr> <note-id>。 -
批准:
glab mr approve 123
自动化审查工作流:
对于重复性审查任务,请使用此技能在 scripts/ 下附带的自动化脚本
(以下路径均相对于技能自身目录):
scripts/mr-review-workflow.sh 123
scripts/mr-review-workflow.sh 123 "pnpm test"
该脚本会自动:检出 → 运行测试 → 发布结果 → 测试通过后批准。
合并策略
流水线通过后自动合并:
glab mr merge 123 --when-pipeline-succeeds --remove-source-branch
合并输出会准确报告最终的 merge request 状态。不要假设成功执行 glab mr merge --auto-merge 就会显示 Merged!;如果 MR 只是已设置为自动合并,自动化应将已接受状态视为待处理,而不是已合并。
压缩提交:
glab mr merge 123 --squash
合并前变基:
glab mr rebase 123
glab mr merge 123
故障排查
合并冲突:
- 检出 MR:
glab mr checkout 123 - 在编辑器中手动解决冲突
- 提交解决结果:
git add . && git commit - 推送:
git push
无法批准 MR:
- 检查你是否为作者(大多数配置不允许自我批准)
- 验证权限:
glab mr approvers 123 - 确保 MR 不是草稿状态
需要流水线但未运行:
- 检查分支中是否存在
.gitlab-ci.yml - 确认项目已启用 CI/CD
- 手动触发:
glab ci run
“MR already exists”错误:
- 列出来自该分支的现有 MR:
glab mr list --source-branch <branch> - 如果旧 MR 已过时,则关闭:
glab mr close <id> - 或更新现有 MR:
glab mr update <id> --title "New title"
相关技能
处理议题:
- 创建和管理议题,请参阅
glab-issue - 使用
glab mr for <issue-id>创建与议题关联的 MR - 脚本:
scripts/create-mr-from-issue.sh可自动创建分支和 MR
CI/CD 集成:
- 合并前查看流水线状态,请参阅
glab-ci - 使用
glab mr create --auto-merge提前请求自动合并,或对现有 MR 使用glab mr merge --when-pipeline-succeeds
自动化:
- 脚本:
scripts/mr-review-workflow.sh,用于自动化审查和测试工作流
列出和定位 MR 讨论
glab mr note list 的文本输出会为每条非系统讨论显示备注 ID 和 8 个字符的讨论 ID 前缀,以及相对和绝对时间戳。将省略号前的字符直接传给 --reply;如果工作流需要完整的讨论 ID,请使用 JSON。使用经验证的标识符调用 resolve、reopen 或 --reply,而不要抓取作者或正文文本。
# Filter the text view
glab mr note list 123 --type diff --state unresolved
glab mr note list 123 --file src/app.ts
# Prefer JSON when an automation needs stable IDs
glab mr note list 123 --output json \
--jq '.[] | {discussion_id: .id, note_ids: [.notes[].id]}'
# Extract full discussion IDs
glab mr note list 123 -F json --jq '.[].id'
# Act on the verified identifier
glab mr note resolve 123 <discussion-or-note-id>
glab mr note reopen 123 <discussion-or-note-id>
上游生成的帮助文档展示了使用外部 jq 管道进行相同提取的方式。此技能集更倾向于使用受支持的内置 --jq 标志,这样筛选就在 glab 内完成,并可避免启动单独的 shell 进程。
--type 接受 all、general、diff 或 system;--state 接受 all、resolved 或 unresolved;--file 将结果限制为某一路径上的 diff 备注。这些子命令仍处于实验阶段,因此在针对混用不同版本 glab 的场景编写脚本时,请确认当前帮助信息。
在文本输出中,默认的 --type all 会同时包含系统备注和常规讨论。如果只想查看系统活动,请使用 --type system;如果自动化不应将分配或状态事件解析为用户反馈,请选择范围更窄的备注类型。
原生 MR 备注流程(glab mr note create)
glab mr note create 是发布新 MR 讨论的首选命令。
适合使用原生 glab mr note create 的情况
# New top-level discussion/comment
glab mr note create 123 -m "Please add a regression test"
# Non-resolvable note for automation/status output
glab mr note create 123 -m "Build status: green" --resolvable=false
# Reply to an existing discussion thread
glab mr note create 123 --reply abc12345 -m "Fixed in the latest push"
# File-level diff comment
glab mr note create 123 --file src/app.ts -m "General concern on this file"
# Line comment on the new side of the diff
glab mr note create 123 --file src/app.ts --line 84 -m "This branch can return null"
# Range comment on the new side
glab mr note create 123 --file src/app.ts --line 84:96 -m "Consider extracting this block"
# Comment on a removed line from the old side
glab mr note create 123 --file src/app.ts --old-line 37 -m "Why was this guard removed?"
上游帮助文档中值得牢记的标志规则:
--reply用于回复现有讨论线程,而不是新建讨论。--reply接受完整的讨论 ID,或至少 8 个字符且唯一的前缀。- 默认情况下,新建的顶层备注会创建为可解决的讨论线程。对于不应阻碍要求所有线程都已解决的项目的机器人或状态评论,请使用
--resolvable=false。 --line和--old-line必须与--file一起使用,且两者不能同时使用。--file、--reply和--unique不能同时使用。--resolvable=false不能与--reply、--file、--line或--old-line一起使用。- 待处理的评审评论应使用
glab mr note draft create,而不是mr note create --draft。草稿创建支持 diff 定位、回复和附件,但不支持--unique、--resolvable或--internal。 --internal会创建仅项目成员可见的备注。它不能与 diff 定位(--file、--line或--old-line)一起使用;新建的顶层内部备注也不得显式指定--resolvable=true。- 使用
--reply --internal时,glab 会拒绝向公开线程发布内容。回复内部线程时,即使省略--internal,回复仍会保持为内部内容。 --attach可以重复使用,也可以提供完整的备注正文;由于每次上传都会生成新的 URL,因此它不能与--unique一起使用。- 对于
mr note update,仅提供附件输入会将内容追加到当前备注正文;同时使用--message和附件时,会替换正文,然后追加新的引用。 - 如果要发布文件级 diff 评论,请同时省略
--line和--old-line。
待处理的审核评论
如果想先暂存多条审核意见,再让它们对其他人可见,请使用待处理评论:
glab mr note draft create 123 --file src/app.ts --line 84 \
-m "This branch can return null"
glab mr note draft create 123 --reply abc12345 \
-m "I reproduced this locally"
# Inspect only your own pending comments before publishing
glab mr note draft list 123 --output json
# Review state is not an approval; use glab mr approve separately when appropriate.
glab mr note draft publish 123 \
--message "A few blockers, see the comments." \
--reviewer-state requested_changes \
--yes
publish 只会发布你自己的待处理评论。--reviewer-state 接受 requested_changes 或 reviewed;两者都不会记录正式批准。如果合并请求由你创建,除非你也被列为审核者,否则 GitLab 会忽略 --reviewer-state,而 glab 会针对这一情况发出警告。--internal 仅适用于可选的摘要备注,且需要 --message。非交互运行需要 --yes;如果没有待处理评论,发布操作会失败。即使评论本身仍处于待处理状态,附件也会立即上传。
draft create 会打印待处理评论的数字 ID。请保留此 ID,以便用于 draft update 或 draft delete;它不是已发布备注 ID,也不是讨论 ID。提供 MR 时,解析器要求草稿 ID 放在最后,尽管渲染器会将必填参数列在前面:
# Inspect the selected draft before changing it
glab mr note draft list 123 --output json
glab mr note draft update 123 456 -m "Revised finding"
# Delete only after explicit approval; this affects your pending review
glab mr note draft delete 123 456 --yes
draft update 只会修改正文,不会修改其差异位置;由于无法保留位置,不能通过 CLI 更新带有图片位置的草稿。仅更新附件时,附件会追加到现有正文;明确指定消息时,则会先替换正文,再追加附件引用。除非提供 --yes,否则 draft delete 会提示确认。草稿命令组仅对你自己的待处理评论生效;不会列出、编辑、删除或发布其他审核者的草稿。请勿使用已移除的 mr note publish 命令:其 --help 会回退到父级帮助信息,不能证明该命令仍然存在。
适合保留辅助工具/脚本方案的情况
如果自动化需要更可靠的锚定保证,请使用随附的内联评论辅助工具或原始 glab api JSON 正文方案,尤其是在以下情况:
- 必须验证 GitLab 创建的是真正的内联讨论,而不是 MR 根备注
- 要批量发布许多评论
- 目标差异比较棘手(新文件、重命名文件、复杂路径或行代码回退情况)
对于大多数交互式回复和差异评论工作流,glab mr note create 已经足够。该辅助工具仍然适用于构建稳健的自动化审核流水线。
在 MR 差异上发布内联评论
glab api --field 的问题
在 glab v1.118.0 中,如果 glab api --field position[new_line]=N 会创建 JSON 请求正文,该命令会立即失败:
a field name containing a bracket is not supported in a JSON request body
请勿使用带方括号的字段名称来构建内联 MR 讨论正文。较早的表单式位置负载也容易出问题,包括:
- 完全新增的文件(差异中有
new_file: true) - 路径复杂或经过编码的文件
- 任何无法在表单编码后保留的嵌套位置字段
请使用带 JSON 正文的 --input - 创建内联讨论。务必检查返回备注的 position 字段,以便自动化流程检测根 MR 备注或锚定失败。
解决方法:始终使用 JSON 正文
通过 glab api 和字面 JSON 请求正文发布内联评论。认证由 glab 处理;切勿读取、复制、记录或打印已存储的令牌值:
set -euo pipefail
HOST="gitlab.com"
PROJECT_PATH="mygroup/myproject"
MR_IID="42"
FILE_PATH="src/utils/helpers.ts"
LINE="16"
BODY="Your comment here"
# Confirm the exact GitLab host and visible account before creating a discussion.
glab auth status --hostname "$HOST"
glab api --hostname "$HOST" /user | jq '{username: .username, name: .name}'
PROJECT_ID="$(python3 -c 'import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1], safe=""))' "$PROJECT_PATH")"
# Always fetch fresh SHAs from the current MR version; never use cached values.
VERSION_JSON="$(glab api --hostname "$HOST" "/projects/$PROJECT_ID/merge_requests/$MR_IID/versions" | jq '.[0]')"
python3 - "$VERSION_JSON" "$FILE_PATH" "$LINE" "$BODY" <<'PY' |
import json
import sys
version = json.loads(sys.argv[1])
file_path = sys.argv[2]
line = int(sys.argv[3])
body = sys.argv[4]
json.dump({
"body": body,
"position": {
"base_sha": version["base_commit_sha"],
"start_sha": version["start_commit_sha"],
"head_sha": version["head_commit_sha"],
"position_type": "text",
"new_path": file_path,
"new_line": line,
"old_path": file_path,
"old_line": None
}
}, sys.stdout)
PY
glab api --hostname "$HOST" --method POST --header "Content-Type: application/json" --input - \
"/projects/$PROJECT_ID/merge_requests/$MR_IID/discussions" |
jq '{discussion_id: .id, inline: ((.notes[0].position // null) != null)}'
返回的 inline 值必须为 true。如果是 false,请将结果视为 MR 根讨论,不要声称内联锚定成功。
查找正确的行号
行号必须指向差异中的新增行(以 + 为前缀);上下文行和删除行
会导致位置被拒绝:
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)
可复用脚本
对于脚本化或自动化的 MR 审查,请使用此技能随附的辅助脚本 (以下路径均相对于技能自身目录):
# 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.json
批处理文件格式:
[
{ "file": "src/utils/helpers.ts", "line": 16, "body": "Comment 1" },
{ "file": "src/routes/+page.svelte", "line": 58, "body": "Comment 2" }
]
该脚本会让 glab 处理身份验证,通过 glab api 获取最新的 SHA 和差异,并采用两步锚定策略:
- 首先尝试常规的 JSON
position.new_line行内载荷。 - 如果 GitLab 因
line_code验证错误而拒绝,则计算差异锚点,并使用 JSONposition.line_range.start.line_code/position.line_range.end.line_code重试。
对于以下失败情况,优先采用此重试路径进行恢复:
400 Bad request - Note {:line_code=>["can't be blank", "must be a valid line code"]}
只有在重试也失败时,你更广泛的审查工作流才应回退到 MR 根评论,并明确说明行内锚定失败,同时保留原样的发现内容和审查者身份。
按解决状态筛选讨论线程
# Show only unresolved discussion threads on an MR
glab mr view 123 --unresolved
# Show only resolved threads
glab mr view 123 --resolved
这有助于在合并前快速检查哪些审查线程仍需处理。
glab mr view 的常规文本输出现在会显示源分支和目标分支。请在审查、变基或合并前确认显示的 source → target 方向,尤其是针对派生仓库的合并请求。自动化需要稳定的分支字段而非解析渲染后的文本行时,请使用 --output json。
glab mr list 筛选标志
glab mr list 支持以下筛选和排序标志:
# 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-01
结构化输出
glab mr approvers 支持 --output json / -F json 结构化输出,这对 Agent 自动化很有用。
# View MR approvers with JSON output
glab mr approvers 123 --output json
glab mr approvers 123 -F json
命令参考
如需完整的命令文档和所有标志,请参阅 references/commands.md。
可用命令:
approve- 批准合并请求checkout- 在本地检出 MRclose- 关闭合并请求create- 创建新的 MRdelete- 删除合并请求diff- 查看 MR 中的更改for- 为议题创建 MRlist- 列出合并请求merge- 合并/接受 MRnote- MR 讨论命令;使用glab mr note create添加新评论,另有list、resolve和reopenrebase- 对源分支进行变基reopen- 重新打开合并请求revoke- 撤销批准subscribe/unsubscribe- 管理通知todo- 添加待办事项update- 更新 MR 元数据view- 显示 MR 详情