GitHub vs GitLab Forge Integration in tuicr: 5 Key Differences Explained

tuicr implements GitHub and GitLab integration through separate ForgeBackend trait implementations that differ in CLI dependencies, diff retrieval, comment anchoring, and draft review semantics.

The tuicr terminal UI for code reviews abstracts remote forge interactions behind a common interface, yet each backend handles platform-specific quirks differently. Understanding these distinctions helps users troubleshoot authentication errors, parse target formats correctly, and know what to expect when switching between forges.

CLI Dependencies and Backend Instantiation

Each integration relies on a different official command-line tool.

GitHub requires the gh CLI. The backend is instantiated in src/forge/github/gh.rs, which emits errors such as "GitHub integration requires gh" and "GitHub authentication failed" when prerequisites aren't met.

GitLab requires the glab CLI. Its implementation in src/forge/gitlab/glab.rs produces analogous error messages: "GitLab integration requires glab" and "GitLab authentication failed."

Both backends check for the binary and valid authentication before executing any remote operations.

Remote Detection Priority

The detection logic in src/forge/mod.rs prioritizes GitHub over GitLab.

  • GitHub detection matches remotes whose host contains "github" or matches a configured GitHub Enterprise host
  • GitLab detection runs as a fallback, checking for "gitlab" in the host or consulting glab's configuration file

Users can override automatic detection with explicit flags:

tuicr --forge github pr open 12   # force GitHub backend

tuicr --forge gitlab mr open 3    # force GitLab backend

PR/MR Target Parsing and Identification

The two forges accept different target formats.

Forge Valid target formats
GitHub owner/repo#<number>, full PR URL
GitLab numeric IID, owner/repo#iid, full MR URL, <host>/owner/repo#iid

GitHub parsing lives in src/forge/github/pr_info.rs. GitLab parsing is embedded in src/forge/gitlab/glab.rs and accepts more flexible host-qualified identifiers.

Diff Retrieval: Cumulative vs Commit-Range

The backends retrieve diffs through fundamentally different mechanisms.

GitHub (src/forge/github/gh.rs) uses gh pr diff for the cumulative diff and falls back to the GitHub compare API with Accept: application/vnd.github.diff when needed.

GitLab (src/forge/gitlab/glab.rs) invokes glab mr diff. A critical limitation: the commit-range diff is only available when the MR head is reachable locally. Otherwise, tuicr reports "Commit range diff without local checkout not yet supported for GitLab."

Comment Anchoring and Position Payloads

Inline comment positioning requires platform-specific JSON structures.

GitHub's payload in src/forge/github/submit.rs uses:

  • side field: "LEFT" or "RIGHT"
  • Single line number

GitLab's payload in src/forge/gitlab/glab.rs requires:

  • old_path and new_path
  • old_line and new_line
  • Computed line_code
  • line_range object for multi-line comments

The GitLab backend explicitly notes: "GitLab positions need both old_path and new_path" when constructing the position hash.

Draft Review Semantics

Draft handling diverges significantly between platforms.

GitHub supports native draft reviews. tuicr creates one by omitting the event field (SubmitEvent::Draft). GitHub returns a review ID that is stored on each comment for later submission.

GitLab has no direct draft review API. Instead, tuicr creates a draft note, and the user must publish it through the GitLab web UI. Lines 567-569 in src/forge/gitlab/glab.rs document this limitation: the backend creates the note but cannot transition it to published status programmatically.

Permission and Error Handling Patterns

Both backends emit forge-specific permission errors:

  • GitHub: "Cannot submit review: GitHub token lacks pull request write permission." (src/forge/github/gh.rs, line 908)
  • GitLab: "Cannot submit review: GitLab token lacks merge request write permission." (src/forge/gitlab/glab.rs, line 1221)

GitHub may return HTTP 422 when the selected commit isn't part of the PR. tuicr surfaces a clarified message: "GitHub rejected the review..."

GitLab errors when the MR head has moved or when draft notes cannot be published, with similar user-facing explanations in the GitLab backend file.

Remote Comment Fetching Architectures

The data retrieval patterns differ in protocol and parsing strategy.

Aspect GitHub GitLab
Protocol GraphQL REST via glab api
Thread queries src/forge/github/review_threads.rs Embedded in glab.rs
Summary queries src/forge/github/review_summaries.rs src/forge/gitlab/models.rs
Metadata queries src/forge/github/review_metadata.rs src/forge/gitlab/models.rs

GitLab's response parsing is centralized in src/forge/gitlab/models.rs, while GitHub distributes GraphQL handling across specialized modules.

Summary

  • CLI tools: gh for GitHub, glab for GitLab — both required and checked at runtime
  • Detection order: GitHub prioritized over GitLab in src/forge/mod.rs
  • Target formats: GitLab accepts more flexible host-qualified identifiers
  • Diff retrieval: GitHub always provides cumulative diffs; GitLab commit-range diffs require local checkout
  • Comment anchoring: GitHub uses side+line; GitLab requires old_path/new_path pairs with line_code
  • Draft reviews: GitHub native and publishable; GitLab creates draft notes requiring web UI publication

Frequently Asked Questions

Can tuicr work with both GitHub and GitLab remotes in the same repository?

Yes. The --forge flag forces a specific backend when automatic detection in src/forge/mod.rs is ambiguous. Without the flag, tuicr selects GitHub if any remote matches GitHub hosts, falling back to GitLab only when no GitHub remote exists.

Why does GitLab diff retrieval fail without a local checkout?

GitLab's glab mr diff command can only compute commit-range diffs when the target branch head is present in the local Git repository. The implementation in src/forge/gitlab/glab.rs explicitly checks reachability and emits "Commit range diff without local checkout not yet supported for GitLab" when this requirement isn't met. GitHub's compare API does not have this limitation.

What's the difference between :submit draft on GitHub versus GitLab?

On GitHub, :submit draft creates a pending review via the pull request reviews API by omitting the event field, returning a review ID that tuicr associates with each comment. These drafts can be published later from within tuicr. On GitLab, the same command creates individual draft notes through the notes API, but GitLab provides no programmatic way to publish them — users must complete this step in the GitLab web interface.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →