> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coderabbit.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Review and merge

> Write and submit a review, apply suggestions, and merge or enqueue a pull request from inside Change Stack.

export const EarlyAccessBadge = ({tip = "This feature is in early access. Enable it by setting `early_access: true` in your `.coderabbit.yaml`, or by toggling Early Access on the web interface.", title = "Early Access", cta = "View configuration", href = "/reference/configuration#param-early-access", disabled = false}) => {
  return <Tooltip tip={tip} cta={cta} href={href}>
        <Badge icon="flask-conical" disabled={disabled || undefined}>
            {title}
        </Badge>
    </Tooltip>;
};

export const AzureBadge = ({tip = "This feature is available on Azure DevOps.", title = "Azure", cta, href, disabled = false}) => {
  return <Tooltip tip={tip} cta={cta} href={href}>
        <Badge icon="microsoft" disabled={disabled || undefined}>
            {title}
        </Badge>
    </Tooltip>;
};

export const BitbucketBadge = ({tip = "This feature is available on Bitbucket.", title = "Bitbucket", cta, href, disabled = false}) => {
  return <Tooltip tip={tip} cta={cta} href={href}>
        <Badge icon="bitbucket" disabled={disabled || undefined}>
            {title}
        </Badge>
    </Tooltip>;
};

export const GitLabBadge = ({tip = "This feature is available on GitLab.", title = "GitLab", cta, href, disabled = false}) => {
  return <Tooltip tip={tip} cta={cta} href={href}>
        <Badge icon="gitlab" disabled={disabled || undefined}>
            {title}
        </Badge>
    </Tooltip>;
};

export const GitHubBadge = ({tip = "This feature is available on GitHub and GitHub Enterprise.", title = "GitHub", cta, href, disabled = false}) => {
  return <Tooltip tip={tip} cta={cta} href={href}>
        <Badge icon="github" disabled={disabled || undefined}>
            {title}
        </Badge>
    </Tooltip>;
};

<GitHubBadge /> <GitLabBadge /> <BitbucketBadge /> <AzureBadge disabled tip="Azure DevOps Change Stack artifacts are read-only. No live review, suggestion, or merge action is offered." /> | <EarlyAccessBadge title="Preview" tip="Change Stack is in preview and still changing." />

Change Stack is where you act on the pull request, not only where you read it. You can write and submit a review under your own provider identity, apply CodeRabbit's suggestions to the branch, mark a draft ready, ask CodeRabbit to repair CI or conflicts, and — on GitHub — merge the pull request or place it in its merge queue without leaving the page.

Every action on this page writes to the **live** pull request, while the diff you are reading is pinned to a [snapshot](/change-stack/snapshots). Most of the surprises below follow from that gap.

## Write review comments

You write, edit, discard, and submit review comments through **your own provider identity**. These are your comments on the provider — authored by you, attributed to you, and indistinguishable from ones you would have written in the provider's own review interface. They are not CodeRabbit comments, and submitting them is not a CodeRabbit action.

Comments do not post one at a time. Each one accumulates into a **pending review**, and nothing reaches the provider until you submit that review as a whole.

### Select lines and open the composer

There are four ways in, and they all end at the same comment box:

* **Click a line number** in the gutter to start a range, then **drag down the gutter** to extend it.
* **Shift-click another line number** to extend from the line you already anchored.
* **Use the `+`** that appears in the gutter on the lines you have selected.
* **Press `c`** to comment on whatever the layer context panel currently has focused — the range summary or the comment thread you last stepped to with `Shift`+`J` and `Shift`+`K`. See [Navigate a change](/change-stack/navigation#the-command-palette-and-keyboard).

For a comment about the file as a whole rather than a line in it, use **Add file comment** in the file header. Bitbucket is the exception: it does not accept a comment without a line anchor, so on Bitbucket every comment needs a line.

### Reply to and resolve threads

You can reply to an existing review thread from inside Change Stack, and resolve or reopen it, on GitHub, GitLab, and Bitbucket. That covers CodeRabbit's own findings and your colleagues' comments alike — you do not need to go to the provider to close a conversation out. Azure DevOps artifacts are read-only, so none of it is offered there.

### Attach an image

Use the image button in the composer to attach a screenshot or a diagram to a comment. Pasting from the clipboard is not supported — the attachment goes through the file picker. PNG, JPEG, GIF, and WebP files up to 5 MB each are accepted.

<Info>
  Image uploads are capped at 30 per user per hour. Past that, the upload is rejected with a **Too many image uploads** message and a wait time, and the rejected image is not stored.
</Info>

## Submit the review

Submitting resolves the pending review into one of three provider review events.

| Submit as       | What it does                                                  |
| --------------- | ------------------------------------------------------------- |
| Approve         | Submit an approving review.                                   |
| Comment         | Submit review comments without approval or requested changes. |
| Request changes | Submit a review requesting changes.                           |

## How drafts are held, per provider

Where your unsubmitted comments live depends on the provider, and the difference is worth knowing before you leave a review half-written.

| Provider  | Where the draft lives                                                |
| --------- | -------------------------------------------------------------------- |
| GitHub    | Natively in the provider. The draft is a real GitHub pending review. |
| GitLab    | Held by CodeRabbit. Invisible in the provider until you submit.      |
| Bitbucket | Held by CodeRabbit. Invisible in the provider until you submit.      |

<Warning>
  CodeRabbit-held GitLab and Bitbucket draft reviews **expire after 24 hours** if they have not been submitted. A GitLab draft you leave overnight is gone in the morning, and because the draft was never visible in the provider, nothing there records that it existed. Submit before you stop for the day.
</Warning>

## What happens to a pending review when a new snapshot arrives

Nothing you have written is discarded. A review run completing does not throw away unsubmitted comments on either provider family — but where the draft lives changes what you can do next.

On **GitHub**, the draft is GitHub's own pending review, so a new Change Stack snapshot cannot touch it, and you can keep commenting from an older snapshot. Comments anchor to the commit you were reading, and GitHub marks them outdated if a later commit changed those lines. Change Stack tells you this is happening rather than letting you find out afterwards.

On **GitLab and Bitbucket**, CodeRabbit holds the draft against the merge request or pull request rather than against a commit, so it survives the new snapshot intact. You cannot add to it or submit it from the stale page, though: move to the latest snapshot first. When you submit, the comment positions are rebuilt against the current diff, so a line that moved is re-anchored rather than landing in the wrong place.

<Warning>
  The GitLab and Bitbucket draft expires on a clock, not on a snapshot. See below.
</Warning>

## Apply CodeRabbit suggestions

Some of CodeRabbit's suggestions can be committed straight to the branch. A suggestion is committable when it is a fenced `suggestion` block inside a comment anchored to real lines on the **new** side of the diff, with a valid start-to-end range. A suggestion attached to a removed line, or to no line at all, cannot be applied — and a single comment carrying several suggestion blocks offers each of them separately.

This is available for **GitHub and GitLab** when you have provider write access. **Bitbucket suggestions are refused**, and the two supported providers apply them by different mechanics, so one applying cleanly does not guarantee the other will.

<Warning>
  You must be on the latest snapshot to commit a suggestion, and if someone pushes to the branch between the page loading and you clicking, the commit is **rejected as a conflict** rather than applied to lines that have moved. Reload onto the new snapshot and apply it again.
</Warning>

## Mark a draft ready for review

You can move a draft pull request or merge request to ready for review without leaving Change Stack. It targets the live pull request directly, needs write access, and works on GitHub, GitLab, and Bitbucket. On GitLab it works the way GitLab itself marks readiness — by removing the `Draft:` prefix from the merge request title. Azure DevOps artifacts are read-only, so it is not offered there.

## Merge and merge queue

Merge control is **GitHub-only**. Direct merge and merge-queue controls are not offered for GitLab, Azure DevOps, or Bitbucket; on those providers, merge on the provider itself.

An eligible GitHub reviewer can merge the pull request directly or place it in a required merge queue. The control requires provider write access, a current artifact, and a mergeable live pull request. Whether you *should* merge — merge readiness, remaining blockers, unresolved findings — is assessed on [findings](/change-stack/findings); this page covers the act itself.

The control resolves to one of four actions: **merge** the pull request directly, **enqueue** it into a required merge queue, nothing to do because it is already **queued**, or **unavailable** because no safe merge action exists.

<Warning>
  The diff you are reading is pinned to a snapshot, but merging targets the **live head**. The merge control refuses a stale artifact rather than merging code you have not seen. Switch to the latest snapshot before merging.
</Warning>

### Why merge is unavailable

When the action resolves to Unavailable, one of eight reasons explains it. This is the table to reach for when the merge control is there but will not act.

| Reason                  | What it means                                                                          | What to do                                                                                                                    |
| ----------------------- | -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Artifact stale          | The displayed artifact omits commits present on the live head.                         | Switch to the latest snapshot, then merge.                                                                                    |
| Blocked                 | Conflicts, draft state, required review, or failing checks block merging.              | Clear the blocking condition: resolve conflicts, mark the draft ready for review, get the required review, or fix the checks. |
| No push access          | The viewer lacks confirmed push access.                                                | Get provider write access to the repository.                                                                                  |
| No merge method allowed | Repository settings allow no direct merge strategy.                                    | Change the repository's merge-strategy settings.                                                                              |
| Merge methods unknown   | The accepted merge strategies could not be determined.                                 | Reload the page; if it persists, merge on GitHub.                                                                             |
| Merge queue unknown     | The merge-queue requirement could not be determined.                                   | Reload the page; if it persists, merge on GitHub.                                                                             |
| No pull request         | Change Stack could not read pull-request status — usually a reduced or read-only path. | Merge on GitHub.                                                                                                              |
| Not open                | The pull request is merged or closed.                                                  | Nothing to do.                                                                                                                |

### Merge methods

The usual three, subject to what the repository allows: a **merge commit**, a **squash** into one commit, or a **rebase** onto the base branch.

### What comes back after you act

Unavailable reasons stop you before you attempt. **Rejection reasons come back after you attempt** — the action was offered, you took it, and the provider or a safety guard declined it. The two sets are different, and confusing them wastes time: a rejection usually means the world moved between the moment the action was prepared and the moment it ran.

An attempt ends as **merged**, **queued** into the merge queue, or **rejected** by the provider or by a safety guard. A rejection carries one of seven reasons.

| Rejection reason | Meaning                                              |
| ---------------- | ---------------------------------------------------- |
| Head moved       | The live head changed after the action was prepared. |
| Base moved       | The live base changed after the action was prepared. |
| Not mergeable    | Provider state does not permit merging.              |
| Not queueable    | Provider state does not permit queueing.             |
| Queue required   | Repository rules require the merge queue.            |
| Already merged   | The pull request was already merged.                 |
| Already queued   | The pull request was already in the queue.           |

### Merge queue states

Once the pull request is in the queue, its entry reports as **queued**, **awaiting checks**, **mergeable**, **unmergeable**, or **locked**. Only unmergeable needs you: the queued pull request cannot merge as it stands and will not proceed on its own.

## Start a Coding Agent task

You can launch a Coding Agent task from an eligible Change Stack finding, rather than writing the fix yourself. The offer appears only when your plan, your repository write access, the current-snapshot state, and the provider connection all allow it — a finding you are reading on an older snapshot will not offer one.

Change Stack decides whether to offer the task and nothing more. Task execution, patch handling, traces, and retries belong to Coding Agent and are outside this feature; they are not documented here.

## Command comments

You can ask CodeRabbit to do two specific repairs by posting a command comment on the pull request.

| Command           | What it asks for                           |
| ----------------- | ------------------------------------------ |
| Fix CI            | Ask CodeRabbit to repair failing CI.       |
| Resolve conflicts | Ask CodeRabbit to resolve merge conflicts. |

For what CodeRabbit actually does once asked, see [Finishing Touches](/finishing-touches).

<Warning>
  Posting a command comment is not idempotent. Repeating the same request can create another provider comment, so a second click after an apparent no-response leaves two comments on the pull request rather than retrying the first.
</Warning>

## What's next

<CardGroup cols={1}>
  <Card title="Understand findings" icon="list-checks" href="/change-stack/findings" horizontal>
    Decide whether the pull request is ready before you use the merge control.
  </Card>

  <Card title="Provider support" icon="git-compare" href="/change-stack/provider-support" horizontal>
    Check which of these actions your provider offers before you plan a review around them.
  </Card>
</CardGroup>
