git-pr

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

PR and MR Workflows

PR与MR工作流

Primary skill for pull request and merge request workflows across GitHub and GitLab. Covers the full lifecycle: creation, review queries, comment handling, line-specific comments, and merging. All recipes use minimal field sets for token efficiency.
这是跨GitHub和GitLab的拉取请求(PR)与合并请求(MR)工作流的核心技能。涵盖完整生命周期:创建、评审查询、评论处理、行级评论以及合并。所有方案均使用最小字段集以提升令牌效率。

Context Check (Do This First)

上下文检查(先执行此步骤)

Before starting any PR workflow, detect the current state. This determines the right action:
bash
undefined
开始任何PR工作流之前,请检测当前状态。这将决定后续的正确操作:
bash
undefined

Check if a PR exists for the current branch (allowlisted, zero approval)

检查当前分支是否存在PR(已加入白名单,零审批)

gh pr view --json number,state,reviewDecision,reviewRequests,title 2>/dev/null

| Result                                     | Next action                                                |
|--------------------------------------------|------------------------------------------------------------|
| PR exists, `CHANGES_REQUESTED`             | Fetch unresolved threads (see Review Comment Handling)      |
| PR exists, `REVIEW_REQUIRED` or has pending `reviewRequests` | Check review state or wait for reviewers  |
| PR exists, a bot pending in REST `requested_reviewers` (Copilot shows as `Copilot`) | Auto-review in flight -- wait for it (Bot Review Loop); do NOT re-request |
| PR exists, unresolved review comments      | Address the comments first (Review Comment Handling); never request a new review over outstanding ones |
| PR exists, `APPROVED`                      | Check CI status or proceed with merge                      |
| PR exists, no review decision yet          | Check CI status, review state, or push more changes        |
| No PR for current branch                   | Create a PR (see PR/MR Creation)                           |

This avoids offering to create a PR when one already exists, and immediately surfaces pending review work. The `reviewDecision` field reliably indicates whether a reviewer has requested changes without needing to fetch individual threads.

**Auto-review is an optional setting -- never assume it either way (GitHub):** automatic Copilot code review comes from either a repo/org **ruleset** or the author's **personal** Copilot setting, so its presence varies between accounts, orgs, and even repos of the same owner. When enabled it requests Copilot on every **non-draft** PR at creation (and when a draft is marked ready for review), so a freshly created PR may already have a pending bot request or bot comments minutes later -- and on other repos nothing fires at all. The ruleset source is detectable read-only (the `copilot_code_review` rule via `gh api repos/{owner}/{repo}/rules/branches/{branch}`; see `references/copilot-review-config.md`), but the personal setting has no API -- so an empty ruleset check still means **detect, don't assume**: check for a pending request or an existing bot review first, and only request one if neither shows up; otherwise you get a duplicate round. **Gotcha:** the pending bot request is only visible via `gh api repos/{owner}/{repo}/pulls/{n}/requested_reviewers` (login `Copilot`) -- `gh pr view --json reviewRequests` omits bot reviewers and stays empty.

**Bot reviews cost money (Copilot) or quota (CodeRabbit) -- budget rounds deliberately.** Every Copilot review, including each re-request, bills fully: 13 premium requests on legacy annual plans (up to ~23 reviews/month on Pro -- the pool is shared with all premium features), or token-metered AI credits + Actions minutes on current plans. CodeRabbit PR reviews draw from an hourly per-plan bucket that is **per developer, not per PR** -- all of a developer's open PRs contend for the same review windows. Check the project's **Code Review Policy** (below) before requesting anything billable; prefer local CodeRabbit CLI reviews (see the `coderabbit` skill) to iterate cheaply before the PR-side review.
gh pr view --json number,state,reviewDecision,reviewRequests,title 2>/dev/null

| 结果                                     | 后续操作                                                |
|--------------------------------------------|------------------------------------------------------------|
| PR已存在,状态为`CHANGES_REQUESTED`             | 获取未解决的线程(参见评审评论处理部分)      |
| PR已存在,状态为`REVIEW_REQUIRED`或存在待处理的`reviewRequests` | 检查评审状态或等待评审人员  |
| PR已存在,REST接口的`requested_reviewers`中存在待处理的机器人(Copilot显示为`Copilot`) | 自动评审正在进行中——等待完成(机器人评审循环);请勿重新请求 |
| PR已存在,存在未解决的评审评论      | 先处理这些评论(参见评审评论处理部分);切勿在存在未解决评论的情况下请求新的评审 |
| PR已存在,状态为`APPROVED`                      | 检查CI状态或继续执行合并操作                      |
| PR已存在,尚未做出评审决策          | 检查CI状态、评审状态或推送更多更改        |
| 当前分支无对应PR                   | 创建PR(参见PR/MR创建部分)                           |

这避免了在PR已存在时仍提供创建PR的选项,并能立即显示待处理的评审工作。`reviewDecision`字段可可靠地指示评审人员是否要求更改,无需获取单个线程信息。

**自动评审是可选设置——切勿默认假设其已启用(GitHub)**:Copilot自动代码评审源自仓库/组织的**规则集**或作者的**个人**Copilot设置,因此其启用情况因账户、组织甚至同一所有者的不同仓库而异。启用后,它会在每个**非草稿**PR创建时(以及草稿标记为可评审时)请求Copilot进行评审,因此新创建的PR可能在几分钟后就已有待处理的机器人请求或机器人评论——而在其他仓库中则不会触发任何操作。规则集来源可通过只读方式检测(通过`gh api repos/{owner}/{repo}/rules/branches/{branch}`获取`copilot_code_review`规则;参见`references/copilot-review-config.md`),但个人设置无API接口——因此即使规则集检查为空,也需**检测而非假设**:先检查是否存在待处理请求或已有的机器人评审,仅当两者都不存在时才请求评审;否则会导致重复评审轮次。**注意事项**:待处理的机器人请求仅能通过`gh api repos/{owner}/{repo}/pulls/{n}/requested_reviewers`(登录名`Copilot`)查看——`gh pr view --json reviewRequests`会忽略机器人评审人员,结果为空。

**机器人评审会产生费用(Copilot)或消耗配额(CodeRabbit)——需谨慎规划评审轮次**。每次Copilot评审(包括每次重新请求)都会全额计费:旧版年度计划包含13次高级请求(Pro计划每月约23次评审——配额与所有高级功能共享),当前计划则按令牌计量AI积分+Actions分钟数计费。CodeRabbit PR评审从每个开发者的每小时计划配额中扣除——开发者的所有开放PR会竞争同一评审窗口。在请求任何计费评审前,请查看项目的**代码评审策略**(如下);在PR端评审前,优先使用本地CodeRabbit CLI评审(参见`coderabbit`技能)以低成本迭代。

When to Use

使用场景

  • Creating PRs or MRs -- draft workflows, fill patterns, title format
  • Addressing PR/MR review feedback -- "fix PR comments", "address review", "handle feedback", "resolve review threads"
  • Responding to code review -- evaluating reviewer comments, replying, resolving threads
  • Checking review state -- approvals, pending reviewers, review decisions
  • Querying PR/MR data -- files changed, commits, labels, linked issues
  • Posting comments on PRs/MRs -- line-specific comments, thread replies
  • Looping bot review rounds (GitHub only; Copilot, CodeRabbit) -- re-request the bot, wait for the async review, address comments, repeat until no valid comments remain ("loop the Copilot review", "loop 3 rounds")
  • Configuring Copilot code review -- auto-review rulesets, review effort, custom instructions, billing/quota checks
  • Configuring tool allowlists -- auto-approval patterns for read-only commands
  • 创建PR或MR——草稿工作流、填充模板、标题格式
  • 处理PR/MR评审反馈——“修复PR评论”、“处理评审意见”、“处理反馈”、“解决评审线程”
  • 回复代码评审——评估评审人员评论、回复、解决线程
  • 检查评审状态——审批情况、待处理评审人员、评审决策
  • 查询PR/MR数据——更改的文件、提交记录、标签、关联问题
  • 在PR/MR上发布评论——行级评论、线程回复
  • 循环机器人评审轮次(仅GitHub;Copilot、CodeRabbit)——重新请求机器人评审、等待异步评审、处理评论、重复直到无有效评论(“循环Copilot评审”、“循环3轮”)
  • 配置Copilot代码评审——自动评审规则集、评审力度、自定义指令、计费/配额检查
  • 配置工具白名单——只读命令的自动审批模式

Critical Rules

关键规则

  1. Prefer CLI subcommands over raw API calls. Subcommands handle pagination, error formatting, and repo detection. Only use
    gh api
    /
    glab api
    for operations not covered by subcommands (line comments, thread resolution, GraphQL).
  2. Use
    --json field1,field2
    with
    gh
    to filter output.
    This IS the efficiency mechanism -- no
    --jq
    needed for basic queries. Only request fields you actually need.
  3. glab
    has no
    --json field1,field2
    equivalent.
    Use
    -F json | jq '{fields}'
    to filter output for token efficiency.
  4. Use commands exactly as shown in this skill. The commands below are designed to match auto-approval allowlist patterns. Improvising flag order or adding unexpected flags may trigger permission prompts.

  1. 优先使用CLI子命令而非原始API调用。子命令会处理分页、错误格式化和仓库检测。仅当子命令未覆盖相关操作时(行级评论、线程解决、GraphQL),才使用
    gh api
    /
    glab api
  2. 使用
    --json field1,field2
    gh
    配合过滤输出
    。这是提升效率的机制——基础查询无需使用
    --jq
    。仅请求实际需要的字段。
  3. glab
    --json field1,field2
    等效参数
    。使用
    -F json | jq '{fields}'
    过滤输出以提升令牌效率。
  4. 严格按照本技能中展示的命令执行。以下命令专为匹配自动审批白名单模式设计。随意调整标志顺序或添加意外标志可能触发权限提示。

Provider Detection

服务商检测

bash
git remote get-url origin
Remote URL containsProviderCLIPR term
github.com
GitHub
gh
PR
gitlab.com
or self-hosted GitLab
GitLab
glab
MR
If ambiguous or both present, ask the user.

bash
git remote get-url origin
远程URL包含服务商CLI工具请求术语
github.com
GitHub
gh
PR
gitlab.com
或自托管GitLab
GitLab
glab
MR
若存在歧义或两者都存在,请询问用户。

Read-Only vs Write Classification

只读与写入分类

  • Read-only (safe to auto-approve):
    view
    ,
    list
    ,
    status
    ,
    diff
    ,
    checks
    ,
    search
  • Write (require user approval):
    create
    ,
    edit
    ,
    merge
    ,
    close
    ,
    reopen
    ,
    comment
    ,
    review
    ,
    approve
Reference: See
references/allowlist.md
for tiered auto-approval patterns.

  • 只读(可安全自动审批):
    view
    list
    status
    diff
    checks
    search
  • 写入(需用户审批):
    create
    edit
    merge
    close
    reopen
    comment
    review
    approve
参考:参见
references/allowlist.md
获取分层自动审批模式。

PR/MR Summary (Current Branch)

PR/MR摘要(当前分支)

GitHub:
bash
gh pr view --json number,title,state,isDraft,reviewDecision,mergeable,baseRefName,headRefName
GitLab:
bash
glab mr view -F json | jq '{iid:.iid,title:.title,state:.state,draft:.draft,merge_status:.merge_status,target:.target_branch,source:.source_branch}'
GitHub:
bash
gh pr view --json number,title,state,isDraft,reviewDecision,mergeable,baseRefName,headRefName
GitLab:
bash
glab mr view -F json | jq '{iid:.iid,title:.title,state:.state,draft:.draft,merge_status:.merge_status,target:.target_branch,source:.source_branch}'

PR/MR Summary (By Number)

PR/MR摘要(按编号)

GitHub:
bash
gh pr view {number} --json number,title,state,isDraft,reviewDecision,mergeable,baseRefName,headRefName
GitLab:
bash
glab mr view {iid} -F json | jq '{iid:.iid,title:.title,state:.state,draft:.draft,merge_status:.merge_status,target:.target_branch,source:.source_branch}'
GitHub:
bash
gh pr view {number} --json number,title,state,isDraft,reviewDecision,mergeable,baseRefName,headRefName
GitLab:
bash
glab mr view {iid} -F json | jq '{iid:.iid,title:.title,state:.state,draft:.draft,merge_status:.merge_status,target:.target_branch,source:.source_branch}'

Review State

评审状态

Reference: See
references/review-queries.md
for advanced review queries: per-reviewer state, approval checks, pending reviewers.
GitHub:
bash
gh pr view --json reviews,reviewRequests,latestReviews
GitLab:
bash
glab mr view -F json | jq '{upvotes:.upvotes,reviewers:[.reviewers[]?.username]}'
For detailed approval info (GitLab):
bash
glab api projects/{project_id}/merge_requests/{iid}/approvals | jq '{approved:.approved,approvers:[.approved_by[]?.user.username]}'
参考:参见
references/review-queries.md
获取高级评审查询:按评审人员状态、审批检查、待处理评审人员。
GitHub:
bash
gh pr view --json reviews,reviewRequests,latestReviews
GitLab:
bash
glab mr view -F json | jq '{upvotes:.upvotes,reviewers:[.reviewers[]?.username]}'
获取详细审批信息(GitLab):
bash
glab api projects/{project_id}/merge_requests/{iid}/approvals | jq '{approved:.approved,approvers:[.approved_by[]?.user.username]}'

Files Changed

更改的文件

GitHub:
bash
gh pr diff --name-only
GitLab:
bash
glab mr diff
GitHub:
bash
gh pr diff --name-only
GitLab:
bash
glab mr diff

File Stats

文件统计

GitHub:
bash
gh pr view --json files
GitLab:
bash
glab api projects/{project_id}/merge_requests/{iid}/changes | jq '[.changes[] | {path:.new_path,added:.diff | split("\n") | map(select(startswith("+"))) | length,removed:.diff | split("\n") | map(select(startswith("-"))) | length}]'
GitHub:
bash
gh pr view --json files
GitLab:
bash
glab api projects/{project_id}/merge_requests/{iid}/changes | jq '[.changes[] | {path:.new_path,added:.diff | split("\n") | map(select(startswith("+"))) | length,removed:.diff | split("\n") | map(select(startswith("-"))) | length}]'

List Open PRs/MRs

列出开放的PR/MR

GitHub:
bash
gh pr list --json number,title,author,reviewDecision,updatedAt
GitLab:
bash
glab mr list -F json | jq '[.[] | {iid:.iid,title:.title,author:.author.username,updated:.updated_at}]'
GitHub:
bash
gh pr list --json number,title,author,reviewDecision,updatedAt
GitLab:
bash
glab mr list -F json | jq '[.[] | {iid:.iid,title:.title,author:.author.username,updated:.updated_at}]'

PR/MR Commits

PR/MR提交记录

GitHub:
bash
gh pr view --json commits
GitLab:
bash
glab api projects/{project_id}/merge_requests/{iid}/commits | jq '[.[] | {sha:.short_id,title:.title}]'
GitHub:
bash
gh pr view --json commits
GitLab:
bash
glab api projects/{project_id}/merge_requests/{iid}/commits | jq '[.[] | {sha:.short_id,title:.title}]'

Search PRs/MRs

搜索PR/MR

GitHub:
bash
gh pr list --search "review-requested:@me" --json number,title,url
GitLab:
bash
glab mr list --reviewer=@me -F json | jq '[.[] | {iid:.iid,title:.title,url:.web_url}]'

GitHub:
bash
gh pr list --search "review-requested:@me" --json number,title,url
GitLab:
bash
glab mr list --reviewer=@me -F json | jq '[.[] | {iid:.iid,title:.title,url:.web_url}]'

Create PR/MR (Write -- Manual Approval)

创建PR/MR(写入操作——需手动审批)

ActionGitHubGitLab
Create draft
gh pr create --draft --fill
glab mr create --draft --fill
Create with title
gh pr create --title "feat: ..." --body "..."
glab mr create --title "feat: ..." --description "..."
Create + request Copilot review
gh pr create --title "..." --body "..." --reviewer @copilot
(gh >= 2.88)
n/a
Keep bodies lean. The title follows Conventional Commits (
git-commit
skill); the body is a few sentences or tight bullets on what changes and why -- no restating the diff, no boilerplate sections beyond what the repo's PR template requires.
After creating a non-draft GitHub PR, check
gh api repos/{owner}/{repo}/pulls/{n}/requested_reviewers
before requesting any bot review -- repos with automatic Copilot review already have one in flight (and it will NOT show in
gh pr view --json reviewRequests
). On a repo you know has no auto-review, skip the create-then-edit round-trip and request Copilot at creation with
--reviewer @copilot
; when unsure, create normally and let the detection decide.
操作GitHubGitLab
创建草稿
gh pr create --draft --fill
glab mr create --draft --fill
指定标题创建
gh pr create --title "feat: ..." --body "..."
glab mr create --title "feat: ..." --description "..."
创建并请求Copilot评审
gh pr create --title "..." --body "..." --reviewer @copilot
(gh >= 2.88)
不支持
保持内容简洁。标题遵循约定式提交(
git-commit
技能);正文只需用几句话或简短要点说明更改内容和原因——无需重复diff内容,也无需超出仓库PR模板要求的 boilerplate 部分。
创建非草稿GitHub PR后,在请求任何机器人评审前,请检查
gh api repos/{owner}/{repo}/pulls/{n}/requested_reviewers
——启用自动Copilot评审的仓库可能已有评审在进行中(且不会显示在
gh pr view --json reviewRequests
中)。对于已知自动评审的仓库,可跳过创建后编辑的往返步骤,在创建时使用
--reviewer @copilot
请求Copilot评审;若不确定,则正常创建并由检测逻辑决定是否请求。

Merge (Write -- Manual Approval)

合并(写入操作——需手动审批)

ActionGitHubGitLab
Squash merge
gh pr merge --squash --delete-branch
glab mr merge --squash --remove-source-branch
Rebase merge
gh pr merge --rebase --delete-branch
glab mr merge --rebase --remove-source-branch

操作GitHubGitLab
squash合并
gh pr merge --squash --delete-branch
glab mr merge --squash --remove-source-branch
rebase合并
gh pr merge --rebase --delete-branch
glab mr merge --rebase --remove-source-branch

Review Comment Handling

评审评论处理

Reference: See
references/pr-comment-workflow.md
for the full opinionated workflow with all command patterns and examples.
The workflow has two distinct phases -- never mix them:
Phase 1: Analyze and Fix (local work, no GitHub API writes, zero approvals)
  1. Fetch all unresolved review threads in a single GraphQL query with inline
    --jq
    filter
  2. For each thread: read the file at the referenced path+line, check if the comment is valid by researching the codebase (patterns, conventions, CLAUDE.md, git log)
  3. Be critical -- validate each comment against actual code before accepting. Reviewers can be wrong.
  4. Make all necessary code fixes -- without adding code comments that narrate the fix or restate what the code already reads
  5. Commit and push the fixes -- the message describes the change itself, never the review process (no "address review feedback", bot names, or round numbers; see the
    git-commit
    skill)
Phase 2: Reply and Resolve (one batched command, one approval) 6. Combine all replies and all resolves into a single
&&
-chained command 7. REST replies first, then a single GraphQL mutation with aliases to batch-resolve all handled threads 8. Leave "Needs discussion" threads unresolved
This ordering matters: pushing fixes first ensures reviewers see the changes when they read replies. Never reply to a comment claiming "Fixed" before the fix is actually pushed.
参考:参见
references/pr-comment-workflow.md
获取完整的标准化工作流,包含所有命令模式和示例。
工作流分为两个不同阶段——切勿混淆:
阶段1:分析与修复(本地工作,无GitHub API写入操作,零审批)
  1. 通过单个GraphQL查询结合内联
    --jq
    过滤器获取所有未解决的评审线程
  2. 针对每个线程:读取引用路径+行对应的文件,通过研究代码库(模式、约定、CLAUDE.md、git日志)检查评论是否有效
  3. 保持批判性——在接受评论前验证其是否符合实际代码。评审人员也可能出错。
  4. 进行所有必要的代码修复——无需添加说明修复过程或重复代码内容的注释
  5. 提交并推送修复——提交信息描述更改本身,切勿提及评审流程(如“处理评审反馈”、机器人名称或轮次编号;参见
    git-commit
    技能)
阶段2:回复与解决(单个批处理命令,一次审批) 6. 将所有回复和解决操作合并为一个
&&
链式命令 7. 先执行REST回复,再通过单个带别名的GraphQL突变批量解决所有已处理的线程 8. 保留“需要讨论”的线程为未解决状态
此顺序至关重要:先推送修复可确保评审人员在查看回复时能看到更改内容。切勿在修复实际推送前回复评论称“已修复”。

Fetch Unresolved Threads (Zero Approvals)

获取未解决线程(零审批)

GitHub -- one command with
$(...)
substitution. Generate as a single line and do NOT prepend variable assignments (
OWNER=...
,
REPO=...
) -- both break allowlist matching:
bash
gh api graphql -f query="{ repository(owner: \"$(gh repo view --json owner --jq '.owner.login')\", name: \"$(gh repo view --json name --jq '.name')\") { pullRequest(number: $(gh pr view --json number --jq '.number')) { reviewThreads(first: 100) { nodes { id isResolved isOutdated path line startLine comments(first: 20) { nodes { id databaseId body author { login } } } } } } } }" --jq '[.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved==false)]'
Returns only unresolved threads directly.
Response field mapping (critical -- using wrong ID causes silent failures):
FieldFormatUse for
thread
.id
PRRT_...
(node ID)
resolveReviewThread
mutation
comment
.databaseId
2949637341
(numeric)
REST reply endpoint
comment
.id
PRRC_...
(node ID)
Not typically needed
GitLab (REST):
bash
glab api projects/{project_id}/merge_requests/{iid}/discussions --paginate | jq '[.[] | select(.notes[0].resolvable==true and .notes[0].resolved==false) | {id:.id,path:.notes[0].position.new_path,line:.notes[0].position.new_line,body:.notes[0].body,author:.notes[0].author.username}]'
GitHub——使用
$(...)
替换的单个命令。生成单行命令,且不要添加变量赋值(
OWNER=...
REPO=...
)——两者都会破坏白名单匹配:
bash
gh api graphql -f query="{ repository(owner: \"$(gh repo view --json owner --jq '.owner.login')\", name: \"$(gh repo view --json name --jq '.name')\") { pullRequest(number: $(gh pr view --json number --jq '.number')) { reviewThreads(first: 100) { nodes { id isResolved isOutdated path line startLine comments(first: 20) { nodes { id databaseId body author { login } } } } } } } }" --jq '[.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved==false)]'
直接返回仅包含未解决线程的结果。
响应字段映射(关键——使用错误ID会导致静默失败)
字段格式用途
线程
.id
PRRT_...
(节点ID)
resolveReviewThread
突变操作
评论
.databaseId
2949637341
(数字)
REST回复端点
评论
.id
PRRC_...
(节点ID)
通常不需要
GitLab(REST):
bash
glab api projects/{project_id}/merge_requests/{iid}/discussions --paginate | jq '[.[] | select(.notes[0].resolvable==true and .notes[0].resolved==false) | {id:.id,path:.notes[0].position.new_path,line:.notes[0].position.new_line,body:.notes[0].body,author:.notes[0].author.username}]'

Reply and Resolve (One Batched Command)

回复与解决(单个批处理命令)

GitHub -- combine all REST replies and a batch GraphQL resolve mutation into one
&&
-chained command. Reply uses
databaseId
(numeric), resolve uses thread
id
(PRRT_ node ID):
bash
gh api repos/{owner}/{repo}/pulls/{pr}/comments/{databaseId_1}/replies -f body="Fixed in {sha} -- {explanation}" && \
gh api repos/{owner}/{repo}/pulls/{pr}/comments/{databaseId_2}/replies -f body="Addressed in {sha}" && \
gh api graphql -f query="
mutation {
  t1: resolveReviewThread(input: {threadId: \"PRRT_thread1\"}) { thread { isResolved } }
  t2: resolveReviewThread(input: {threadId: \"PRRT_thread2\"}) { thread { isResolved } }
}"
GitLab:
bash
glab api projects/{id}/merge_requests/{iid}/discussions/{disc_1}/notes --method POST --field "body=Fixed in {sha}" && \
glab api projects/{id}/merge_requests/{iid}/discussions/{disc_1} --method PUT --field "resolved=true" && \
glab api projects/{id}/merge_requests/{iid}/discussions/{disc_2}/notes --method POST --field "body=Addressed" && \
glab api projects/{id}/merge_requests/{iid}/discussions/{disc_2} --method PUT --field "resolved=true"

GitHub——将所有REST回复和批量GraphQL解决突变合并为一个
&&
链式命令。回复使用
databaseId
(数字),解决操作使用线程
id
(PRRT_节点ID):
bash
gh api repos/{owner}/{repo}/pulls/{pr}/comments/{databaseId_1}/replies -f body="Fixed in {sha} -- {explanation}" && \
gh api repos/{owner}/{repo}/pulls/{pr}/comments/{databaseId_2}/replies -f body="Addressed in {sha}" && \
gh api graphql -f query="
mutation {
  t1: resolveReviewThread(input: {threadId: \"PRRT_thread1\"}) { thread { isResolved } }
  t2: resolveReviewThread(input: {threadId: \"PRRT_thread2\"}) { thread { isResolved } }
}"
GitLab:
bash
glab api projects/{id}/merge_requests/{iid}/discussions/{disc_1}/notes --method POST --field "body=Fixed in {sha}" && \
glab api projects/{id}/merge_requests/{iid}/discussions/{disc_1} --method PUT --field "resolved=true" && \
glab api projects/{id}/merge_requests/{iid}/discussions/{disc_2}/notes --method POST --field "body=Addressed" && \
glab api projects/{id}/merge_requests/{iid}/discussions/{disc_2} --method PUT --field "resolved=true"

Code Review Policy (Convention)

代码评审策略(约定)

Review preferences are declared in a
Code Review Policy
section of an agent instructions file -- check for one before requesting any review. Two scopes, most specific wins:
  1. Repo policy -- the project's AGENTS.md or CLAUDE.md. AGENTS.md is the preferred home: Copilot code review itself reads the root AGENTS.md, so one file steers both the agent and the reviewer.
  2. User-global policy -- the user's global agent instructions (Claude Code:
    ~/.claude/CLAUDE.md
    ) as the default flow across repos.
Both reviewers are optional. Detect what is actually available (CodeRabbit app installed / CLI authenticated, Copilot ruleset or observed auto-review) and never assume a reviewer exists, is paid for, or should be added.
Reviewer: none
is a valid policy -- human review only. Example:
markdown
undefined
评审偏好声明在代理指令文件的
Code Review Policy
部分——在请求任何评审前请检查是否存在该部分。分为两个范围,更具体的范围优先:
  1. 仓库策略——项目的AGENTS.md或CLAUDE.md文件。AGENTS.md是首选位置:Copilot代码评审本身会读取根目录下的AGENTS.md,因此一个文件即可同时指导代理和评审人员。
  2. 用户全局策略——用户的全局代理指令(Claude Code:
    ~/.claude/CLAUDE.md
    ),作为跨仓库的默认流程。
两种评审人员均为可选。检测实际可用的评审人员(是否安装CodeRabbit应用/CLI已认证、是否存在Copilot规则集或已观察到自动评审),切勿假设评审人员存在、已付费或应添加。
Reviewer: none
是有效的策略——仅使用人工评审。示例:
markdown
undefined

Code Review Policy

Code Review Policy

  • Reviewer: coderabbit # coderabbit | copilot | both | none
  • Copilot billing: legacy # legacy (premium requests) | credits
  • Local review: coderabbit review --committed # run before every push
  • PR review rounds: ask # ask | loop <= N

**When no policy exists (either scope), default conservative:** if an auto-review fired, process that round; then ask before any billable re-request -- and inform the recommendation with the quality of the round's findings (mostly valid substantive issues -> another round likely pays off; mostly noise -> stop). Never initiate billable reviews unprompted on repos without auto-review; loop only when explicitly asked.
  • Reviewer: coderabbit # coderabbit | copilot | both | none
  • Copilot billing: legacy # legacy(高级请求) | credits
  • Local review: coderabbit review --committed # 每次推送前执行
  • PR review rounds: ask # ask | loop <= N

**若不存在策略(任何范围),默认采用保守方式**:若自动评审已触发,则处理该轮次;然后在进行任何计费重新请求前询问用户——并根据该轮次的发现质量给出建议(大多为有效实质性问题->可能值得再一轮;大多为无效信息->停止)。切勿在无自动评审的仓库上未经提示启动计费评审;仅当用户明确要求时才进行循环评审。

Bot Review Loop (GitHub)

机器人评审循环(GitHub)

Reference: See
references/bot-review-loop.md
for the full loop: per-bot config blocks (Copilot, CodeRabbit), the
bot_status
/
bot_tick
driver, polling, and termination logic. Reference: See
references/copilot-review-config.md
for Copilot review configuration: billing models and quota checks, auto-review ruleset detection/management, custom instructions, and the Copilot CLI local review option.
GitHub review bots (Copilot, CodeRabbit) are GitHub-only, asynchronous (~minutes per review), and never block: their review
state
is always
COMMENTED
. The loop is identical per bot; only the identity (which login to filter), the re-request trigger, and the detectable failure/rate-limit/clean-review notices differ -- a per-bot config block sets them. Enablement detection is partial (the Copilot auto-review ruleset is readable, but personal-setting auto-review and overall bot availability are not -- see Context Check above), so
bot_tick
exits
5
when the remote isn't GitHub or the re-request errors; an accepted-but-unanswered request exits
3
(slow or silently unavailable).
Iterate until no valid comments remain. Source a bot's config + the
bot_status
/
bot_tick
driver -- one round is:
  1. Re-request only when needed + wait --
    bot_tick {N}
    first checks for unresolved bot threads (handle those, never re-request over them), then a review at HEAD (a clean CodeRabbit review posts no review object -- its "no actionable comments" walkthrough text or a "Review finished." ack is the clean signal, never a failure or rate limit), then a pending request in REST
    requested_reviewers
    (auto-review on non-draft PR creation usually means round 1 needs no re-request at all). Only if none of those apply does it re-request (Copilot:
    gh pr edit {N} --add-reviewer "@copilot"
    , gh >= 2.88, no auto re-review on push; CodeRabbit: a
    @coderabbitai review
    comment), then polls for the async review. Returns
    0
    clean /
    2
    not clean /
    3
    retry /
    4
    failed (already cooled down ~5 min + re-requested -- re-run to poll) /
    5
    not applicable /
    6
    rate-limited.
  2. Validate, don't blind-fix -- evaluate each unresolved comment (Research Checklist); bots can be out of context or outdated. Fix valid ones (commit + push; the message names the change, never the bot or round), reply with a rationale + resolve invalid ones. To clear every reviewer, run the loop once per active bot and handle human threads via the comment workflow above.
  3. Terminate -- stop when the bot has no comments; on zero valid comments (re-requesting would only resurface them); after ~3 consecutive failed reviews (
    exit 4
    is transient -- e.g. "Copilot encountered an error" -- and
    bot_tick
    retries it with a ~5-min cooldown + re-request; only repeated failure is structural: oversized PR, binary files, quota; escalate); on a rate limit (
    exit 6
    : CodeRabbit -- wait the printed "next review available" window, or skip the bot when Copilot also covers the repo; Copilot -- a hard weekly limit diagnosed from the review run's CI log behind the generic "encountered an error" comment: never re-request before the logged reset date, report cause + date to the user); on unavailability (
    exit 5
    ); after the round cap (default 5, or "loop 3"); or if HEAD is unchanged since the last round.
Rounds are billable -- each Copilot round bills a full review; each CodeRabbit round spends hourly quota that is per developer, not per PR: all your open PRs contend for the same review windows, so with several PRs in flight keep the waiting ones as drafts (excluded from auto-review; marking ready is the request) and promote one at a time -- see the reference's Scheduling Several PRs Through One Bucket. Without an explicit loop instruction or a permissive Code Review Policy: process the auto-review round if one fired, then ask before re-requesting (recommend based on finding quality). Autonomous looping is for when the user asked for it.
Identity gotcha: each bot has a
[bot]
-suffixed login on REST and an unsuffixed one on GraphQL threads (Copilot:
copilot-pull-request-reviewer[bot]
/
copilot-pull-request-reviewer
, plus
Copilot
on REST inline comments; CodeRabbit:
coderabbitai[bot]
/
coderabbitai
). Filter the right one per surface.

参考:参见
references/bot-review-loop.md
获取完整循环流程:按机器人划分的配置块(Copilot、CodeRabbit)、
bot_status
/
bot_tick
驱动程序、轮询和终止逻辑。 参考:参见
references/copilot-review-config.md
获取Copilot评审配置:计费模型和配额检查、自动评审规则集检测/管理、自定义指令以及Copilot CLI本地评审选项。
GitHub评审机器人(Copilot、CodeRabbit)仅适用于GitHub异步(每次评审约需数分钟)且不会阻塞:其评审
state
始终为
COMMENTED
。每个机器人的循环流程相同;仅标识(过滤哪个登录名)、重新请求触发方式和可检测的失败/速率限制/无评论通知有所不同——每个机器人的配置块会设置这些参数。启用情况检测是部分有效的(Copilot自动评审规则集可读取,但个人设置的自动评审和机器人整体可用性无法检测——参见上文的上下文检查),因此当远程仓库不是GitHub或重新请求出错时,
bot_tick
会返回退出码
5
;已接受但未响应的请求返回退出码
3
(缓慢静默不可用)。
迭代直到无有效评论为止。获取机器人的配置+
bot_status
/
bot_tick
驱动程序——一轮评审流程如下:
  1. 仅在需要时重新请求+等待——
    bot_tick {N}
    首先检查是否存在未解决的机器人线程(处理这些线程,切勿在其未解决时重新请求),然后检查HEAD是否已有评审(CodeRabbit无评论时会发布无评审对象——其“无可操作评论”说明文本或“评审完成”确认信息即为无评论信号,而非失败或速率限制),再检查REST接口的
    requested_reviewers
    中是否存在待处理请求(非草稿PR创建时的自动评审通常意味着第一轮无需重新请求)。仅当以上情况都不满足时才重新请求(Copilot:
    gh pr edit {N} --add-reviewer "@copilot"
    ,gh >= 2.88,推送时不会自动重新评审;CodeRabbit:发布
    @coderabbitai review
    评论),然后轮询异步评审结果。返回码:
    0
    无评论 /
    2
    存在评论 /
    3
    重试 /
    4
    失败(已冷却约5分钟+重新请求——重新运行以轮询) /
    5
    不适用 /
    6
    速率受限。
  2. 验证而非盲目修复——评估每个未解决的评论(研究清单);机器人可能脱离上下文或信息过时。修复有效评论(提交+推送;提交信息描述更改,切勿提及机器人或轮次),回复无效评论并说明理由+将其标记为已解决。要清除所有评审人员,请为每个活跃机器人执行一次循环,并通过上述评论工作流处理人工线程。
  3. 终止循环——当机器人无评论时停止;当无有效评论时停止(重新请求只会再次出现相同评论);连续约3次评审失败后停止(退出码
    4
    为临时错误——例如“Copilot遇到错误”——
    bot_tick
    会以约5分钟冷却时间重试+重新请求;仅重复失败为结构性问题:PR过大、二进制文件、配额不足;需升级处理);当速率受限时停止(退出码
    6
    :CodeRabbit——等待显示的“下次评审可用”时间窗口,或当Copilot也覆盖该仓库时跳过此机器人;Copilot——从评审运行的CI日志中诊断出的硬每周限制,该限制隐藏在通用“遇到错误”评论背后:在日志记录的重置日期前切勿重新请求,向用户报告原因+日期);当不可用时停止(退出码
    5
    );达到轮次上限后停止(默认5轮,或“循环3轮”);或自上一轮以来HEAD未更改时停止。
轮次会产生费用——每次Copilot轮次会全额计费;每次CodeRabbit轮次会消耗每小时配额,且该配额按开发者而非PR分配:所有开放PR会竞争同一评审窗口,因此当存在多个PR时,请将等待中的PR保持为草稿状态(自动评审会排除草稿;标记为可评审即为请求评审),并一次仅推进一个——参见参考文档中的《通过单个配额窗口调度多个PR》。若无明确的循环指令或宽松的代码评审策略:处理已触发的自动评审轮次,然后在重新请求前询问用户(根据发现质量给出建议)。仅当用户要求时才自主循环评审。
标识注意事项:每个机器人在REST接口上的登录名带有
[bot]
后缀,在GraphQL线程上的登录名无后缀(Copilot:
copilot-pull-request-reviewer[bot]
/
copilot-pull-request-reviewer
,REST行级评论中显示为
Copilot
;CodeRabbit:
coderabbitai[bot]
/
coderabbitai
)。需根据不同场景过滤正确的标识。

Line-Specific Comments (Write)

行级评论(写入操作)

Reference: See
references/line-comments.md
for full patterns: single-line, multi-line range, replies, edit/delete, batch reviews.
GitHub:
bash
gh api repos/{owner}/{repo}/pulls/{pr}/comments \
  -f body="{comment}" -f path="{file}" -F line={line} -f side=RIGHT \
  -f commit_id="$(gh pr view {pr} --json headRefOid --jq .headRefOid)"
GitLab:
bash
glab api projects/{project_id}/merge_requests/{iid}/discussions --method POST \
  --field "body={comment}" \
  --field "position[base_sha]={base_sha}" \
  --field "position[head_sha]={head_sha}" \
  --field "position[start_sha]={base_sha}" \
  --field "position[position_type]=text" \
  --field "position[new_path]={file}" \
  --field "position[new_line]={line}"

参考:参见
references/line-comments.md
获取完整模式:单行、多行范围、回复、编辑/删除、批量评审。
GitHub:
bash
gh api repos/{owner}/{repo}/pulls/{pr}/comments \
  -f body="{comment}" -f path="{file}" -F line={line} -f side=RIGHT \
  -f commit_id="$(gh pr view {pr} --json headRefOid --jq .headRefOid)"
GitLab:
bash
glab api projects/{project_id}/merge_requests/{iid}/discussions --method POST \
  --field "body={comment}" \
  --field "position[base_sha]={base_sha}" \
  --field "position[head_sha]={head_sha}" \
  --field "position[start_sha]={base_sha}" \
  --field "position[position_type]=text" \
  --field "position[new_path]={file}" \
  --field "position[new_line]={line}"

Read-Only API Endpoints

只读API端点

Reference: See
references/api-readonly.md
for the full list of read-only REST and GraphQL endpoints (PR data, issue timelines, review threads) for both providers.

参考:参见
references/api-readonly.md
获取完整的只读REST和GraphQL端点列表(PR数据、问题时间线、评审线程),涵盖两种服务商。

Key
glab
vs
gh
Differences

glab
gh
的关键差异

Aspect
gh
glab
MR description flag
--body
--description
Delete source branch
--delete-branch
--remove-source-branch
JSON output
--json field1,field2
(filtered)
-F json
(full resource)
jq filtering
--jq '.expr'
(native)
pipe to
| jq '.expr'
Squash on create
--squash
--squash-before-merge
GraphQL
gh api graphql -f query='...'
Not supported (REST only)
Thread resolutionGraphQL mutation
PUT /discussions/:id
with
resolved=true
Approval modelReview states (APPROVED, CHANGES_REQUESTED)Approval rules + approve/revoke
Pagination
--paginate
(subcommands + api)
--paginate
(api only),
-P
(subcommands)

方面
gh
glab
MR描述标志
--body
--description
删除源分支
--delete-branch
--remove-source-branch
JSON输出
--json field1,field2
(已过滤)
-F json
(完整资源)
jq过滤
--jq '.expr'
(原生)
管道到
| jq '.expr'
创建时squash
--squash
--squash-before-merge
GraphQL
gh api graphql -f query='...'
不支持(仅REST)
线程解决GraphQL突变
PUT /discussions/:id
并设置
resolved=true
审批模型评审状态(APPROVED、CHANGES_REQUESTED)审批规则+批准/撤销
分页
--paginate
(子命令+api)
--paginate
(仅api)、
-P
(子命令)

Allowlist

白名单

Reference: See
references/allowlist.md
for tiered
Bash(command:*)
patterns covering all read-only operations -- safe to auto-approve in Claude Code
settings.json
or OpenCode config.
参考:参见
references/allowlist.md
获取分层
Bash(command:*)
模式,涵盖所有只读操作——可安全地在Claude Code
settings.json
或OpenCode配置中设置为自动审批。