Pull & Merge Requests
Create, read, review, and merge pull requests on GitHub and merge requests on GitLab without leaving Codemux.
Pull & Merge Requests
The Review pane in the right panel follows the change request for the branch you're on — its description, checks, comments, and diff — and lets you review and merge it in place.
Codemux supports GitHub and GitLab. It never stores hosting credentials of its own — each product is driven through its own command-line tool, using the credentials that tool already holds.
For the review workflow itself — leaving a verdict, line notes, replying to threads, and merging — see Reviewing & Merging. For the full-screen triage list across every repo you have open, see The Pull Requests Page.
Requirements
Check both from Settings → Source Control, which shows whether each CLI is installed, which account it's signed in as, and the exact command to fix it if not.
Bitbucket and Azure DevOps are recognized but have no integration; a checkout on one is named, marked read-only, and offered an Open in browser button.
Host Detection
Codemux works out which product a checkout talks to by reading its git remotes — no network call, no CLI, no auth. It prefers the remote your branch tracks, then origin, then the first one listed.
github.comandgitlab.com(including their SSH aliases) are matched exactly.- Any hostname containing
githuborgitlabis classified as that product — so self-hostedgitlab.acme.comand GitHub Enterprise ongithub.acme.internalboth work with no configuration. - A neutral domain like
git.acme.internalcan't be guessed. Map it once under Settings → Source Control → Self-hosted servers; that mapping wins over everything else and syncs across your devices. - Anything unclassified is a normal state, not an error — the Review pane simply reports that the checkout isn't a supported repository.
Detection results are cached briefly, but failures aren't, so adding a remote or a host mapping takes effect immediately.
Terminology
Codemux follows the host's own vocabulary. On GitLab the Review pane reads Merge Request, the create button is Create MR, and references render as !12; on GitHub they read Pull Request, Create PR, and #172. Issue references stay # on both.
What Works Per Host
Every action is drawn from a capability the host declares, so a button you can see is a button that works. An operation a host doesn't declare is not drawn at all rather than shown and disabled.
| GitHub | GitLab | |
|---|---|---|
| List, view, create change requests | Yes | Yes |
| CI checks | Yes | Yes (pipeline jobs) |
| Issues | Yes | Yes |
| Read review threads and inline comments | Yes | Yes |
| Reply to a review thread | Yes | Yes |
| Resolve / unresolve a thread | Yes | Diff discussions only |
| Approve | Yes | Yes |
| Request changes | Yes | No — GitLab has no such verdict |
| Line-level review notes | Yes | No — the Code tab is read-only |
| Merge (squash / merge / rebase) | Yes | Yes |
| Draft ↔ ready, close, reopen | Yes | Yes |
| Timeline | Yes | Yes |
| Check out a request into a worktree | Yes | Yes |
| Deployment previews | Yes | No |
Outdated thread labels | Yes | No |
If a backend call is attempted for an undeclared operation it refuses in plain language — "GitLab does not declare this operation — Codemux cannot resolve threads here. Open it in the browser instead."
Where To Open It
- Right panel — click the Review pane in the pane deck. Its tab badges the comment count plus a rollup glyph for the checks: spinner, green check, or red ✕.
- Pull Requests page — the sidebar footer's pull-request icon, or the command palette. See The Pull Requests Page.
- Sidebar PR icon — every workspace with an open request shows a small icon at the bottom-right of its sidebar row. Drafts collapse to a dimmed indicator; the icon clears automatically when you switch branches.
- Agent Chat Context Row — a clickable chip, colored by state.
Requests opened from a side branch
An agent that runs git checkout -b side-branch, commits, pushes, opens a PR, and then checks the worktree back used to leave the sidebar with no PR badge at all — association was strictly by checked-out branch, and the checked-out branch had none.
When the current branch resolves to no PR, Codemux falls back to branches this worktree checked out recently — up to five distinct names, newest first, read from the worktree's own reflog, excluding the current branch, the repository default branch, and detached-HEAD commits. The fallback never runs while you are on the default branch, and it badges open PRs only (the current-branch path still shows merged and closed state). Admitting history there would let a gh pr checkout of someone else's merged PR donate its badge for the whole reflog window.
A side-branch association is a badge and nothing more. It deliberately does not drive:
- PR-completion auto-settle — that branch merging says nothing about a checkout that may still hold uncommitted work. Such a workspace still ages out through the ordinary idle rule.
- The Wrapping up demotion.
- The Review pane, which stays strictly current-branch so "Create Pull Request" is never hidden for the branch you are actually on.
The workspace hover card gains a PR branch row, shown only when the request's branch differs from the checked-out one. Missing information on either side reads as a match — a detached HEAD during a rebase or bisect keeps its badge — so only two known, differing branch names ever un-associate a workspace from its request.
This reflog fallback is a GitHub-path behavior; GitLab workspaces badge from the current branch only.
The Review Pane
With a request open, the pane is a header, three tabs, and an action bar.
The header carries the repo slug, #123 / !123, a state pill (Open, Draft, Merged, Closed), the title, author · age · N files · +adds −dels, and base ← head marked "checked out here". An overflow menu holds Open in browser, Copy URL, and Refresh.
| Tab | What's on it |
|---|---|
| Summary | The checks rail, reviewers, the description, and the comment threads |
| Timeline | Everything that happened to the request, oldest first |
| Code (N) | The full diff, and — on GitHub — line-level review |
Below the body sits the pending-review footer (when you have unsubmitted notes), at most one drift notice, and the action bar. All three are covered in Reviewing & Merging.
Request data refreshes on a poll: the request itself and its checks every 2.5 seconds; reviews, comments, threads, and the timeline every 30 seconds. A failed poll never blanks the content — you get a "Showing data from 4m ago" notice with Retry now instead.
Summary
- Checks rail — a compact rollup, with rows for only the checks that are failing or still running.
- Reviewers — who's been asked and where they landed.
- Description — rendered markdown, foldable past 40 lines, editable in place if you're the author.
- Comments — the review threads. See Review threads.
Timeline
A vertical rail, oldest first, with a filter reading Everything / Host only.
Host events cover opened, reviewed (approved / requested changes / dismissed, with the comment quoted), commented, pushed (abc1234 plus subject, marked "· checks re-ran" on the newest push), force-pushed, merged, closed, reopened, review requested, and renamed. An event Codemux doesn't recognize renders as one plain line rather than being dropped.
Agent runs are the local half of the rail, marked in ember: "Agent run · addressed this thread", what it was pointed at, an optional files · +adds · −dels line, and Open thread to jump to the conversation that did the work. These are local to your install, capped at the 200 most recent, and never pushed to the host — switch the filter to Host only to hide them.
The last row is always live: "12 checks passed, 1 running", dated now.
Creating a Request
When none exists for the current branch, the pane offers Open a pull request / Open a merge request (or Commit and push first, if you haven't pushed).
The form arrives drafted from your commits:
- Title and Description are prefilled from the commits ahead of base — an ember note reads "drafted from your commits", and disappears the moment you type. Nothing is invented: the note never appears when the title was merely humanized from the branch name.
- Base branch picker — changing it re-reads the commit set.
- Use repo template — a chip that prepends your repository's PR template when it has one (GitHub's known paths; GitLab's
.gitlab/merge_request_templates/). - + reviewer — collect reviewers as chips; they're requested after creation. If a request fails, the PR still exists and you're told which handle didn't take.
- Uncommitted work is called out — "3 files have uncommitted changes" with a Review button.
- Draft or Create. The footer notes that it pushes the branch first.
On GitLab a draft is created by prefixing the title with Draft:, which is how GitLab itself marks them.
Labels and an agent-rewrite button are deliberately absent — the backend can't carry them, so they aren't drawn.
CI Checks
The Checks section shows GitHub Actions runs or GitLab pipeline jobs, summarised as a rail with only the failing and running rows expanded. Each row has a status icon, a clickable name, and elapsed time.
Expanding a failing check gives you Full log and Fix with agent. See Handing work to an agent.
On GitLab, pipelines reported by an external system fall back to commit statuses so they still appear.
There is no per-check re-run button. Re-running a job happens on the host.
Incoming Requests
On the default branch, the pane lists incoming requests targeting that base — including from forks. Click a row to open it on the Pull Requests page; use Check out to create a worktree from the request's branch, or Switch if a workspace for it already exists.
When Something Is Unavailable
The Review pane reports the most fundamental problem first, so you're never told to install a CLI you don't need:
| Situation | What you see |
|---|---|
| Host has no integration | "<Product>, read-only" with Open in browser |
| CLI missing | "GitHub CLI (gh) isn't installed" with Install gh |
| CLI not signed in | "Sign in to GitHub" — Sign in copies gh auth login to your clipboard |
| Repo unreachable | "Can't reach this repository" with Retry and the gh auth status command |
| Branch pushed, no request | Open a pull request and View commits |
| Nothing pushed | Commit and push (or Push branch when clean) and Changes |
The same gating applies to the composer's + attach menu and @issue: / @pr: mentions — those rows are disabled with the matching reason rather than failing when you click them. See Attachments.
Limitations
- GitHub and GitLab only. Bitbucket and Azure DevOps are detected and named, but read-only with a browser link.
- No request-changes verdict on GitLab, and no line-level review on GitLab — the Code tab there is a readable diff with no composer.
- No deployments on GitLab.
- Sign-in is per instance. A self-hosted GitLab on a non-default port is a separate
glabentry fromgitlab.com; sign in to each one you use. - No in-app login. Authentication is entirely
gh auth login/glab auth loginin a terminal. - No per-check re-run and no label editing on the create form.
Related
- Reviewing & Merging — verdicts, line notes, threads, and the merge sheet
- The Pull Requests Page — triage across every repo you have open
- Changes — stage and commit before you open a request
- Right Panel — the deck the Review pane lives in