Claude
Skills
Sign in
Back

glab-mr

Included with Lifetime
$97 forever

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.

Code Review

What this skill does


# glab mr

Create, view, and manage GitLab merge requests.

## Quick start

```bash
# 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-branch
```

## Common workflows

### Creating MRs

**From current branch:**
```bash
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
```

**From issue:**
```bash
glab mr for 456  # Creates MR linked to issue #456
```

**Draft MR:**
```bash
glab mr create --draft --title "WIP: Feature X"
```

### Review workflow

1. **List pending reviews:**
   ```bash
   glab mr list --reviewer=@me --state=opened
   ```

2. **Checkout and test:**
   ```bash
   glab mr checkout 123
   npm test
   ```

3. **Leave feedback:**
   ```bash
   # 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"

   # 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?"

   # List discussion threads on the MR (experimental)
   glab mr note list 123

   # Resolve or reopen a discussion by note/discussion ID (experimental)
   glab mr note resolve 3107030349 123
   glab mr note reopen 3107030349 123
   ```

4. **Approve:**
   ```bash
   glab mr approve 123
   ```

**Automated review workflow:**

For repetitive review tasks, use the automation script:
```bash
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:**
```bash
glab mr merge 123 --when-pipeline-succeeds --remove-source-branch
```

**Squash commits:**
```bash
glab mr merge 123 --squash
```

**Rebase before merge:**
```bash
glab mr rebase 123
glab mr merge 123
```

## Troubleshooting

**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.yml` exists 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-issue` for creating/managing issues
- Use `glab mr for <issue-id>` to create MR linked to issue
- Script: `scripts/create-mr-from-issue.sh` automates branch + MR creation

**CI/CD integration:**
- See `glab-ci` for pipeline status before merging
- Use `glab mr create --auto-merge` to request auto-merge up front, or `glab mr merge --when-pipeline-succeeds` on an existing MR

**Automation:**
- Script: `scripts/mr-review-workflow.sh` for automated review + test workflow

## Native MR note flow (`glab mr note create`)

`glab mr note create` is the preferred command surface for posting new MR discussions.

### Use native `glab mr note create` when

```bash
# 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?"
```

Flag rules worth remembering from the upstream help/docs:
- `--reply` targets an existing discussion thread instead of starting a new one.
- `--reply` accepts a full discussion ID or a unique prefix of at least 8 characters.
- By default, new top-level notes are created as resolvable discussion threads. Use `--resolvable=false` for bot/status comments that should not block projects requiring all threads to be resolved.
- `--line` and `--old-line` require `--file` and cannot be used together.
- `--file`, `--reply`, and `--unique` are mutually exclusive.
- `--resolvable=false` cannot be combined with `--reply`, `--file`, `--line`, or `--old-line`.
- Omit both `--line` and `--old-line` when you want a file-level diff comment.

### Keep the helper/script path when

Use the bundled inline-comment helper or raw `glab api` JSON-body approach when you need stronger anchoring guarantees for automation, especially when:
- you must verify that GitLab created an actual inline discussion rather than silently falling back to a general MR note
- you are posting many comments in batch
- you are targeting tricky diffs (new files, renamed files, complex paths, or line-code fallback cases)

`glab mr note create` is now enough for most interactive reply and diff-comment workflows. The helper remains valuable for robust automated review pipelines.

## 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: true` in 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:

```python
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.d
Files: 2
Size: 35.9 KB
Complexity: 45/100
Category: Code Review

Related in Code Review