Skip to content

feat(web): add per-commit diff views - #6102

Open
pranav100000 wants to merge 2 commits into
pingdotgg:mainfrom
pranav100000:feat/diff-pane-commit-views-5881
Open

feat(web): add per-commit diff views#6102
pranav100000 wants to merge 2 commits into
pingdotgg:mainfrom
pranav100000:feat/diff-pane-commit-views-5881

Conversation

@pranav100000

@pranav100000 pranav100000 commented Aug 11, 2026

Copy link
Copy Markdown

Add a "Commits" submenu to the Diff pane (beside the existing "Turns" picker) that lists the current branch's commits; selecting one shows that commit's first-parent diff through the existing diff renderer. Backed by a new GitVcsDriver method that lists commits and loads a single commit's diff on demand. Tests included (185 passing).

Closes #5881.

Note

Add per-commit diff views to the web diff panel

  • Users can now select individual commits from the branch range in the diff panel scope menu and view their isolated diffs, including root commits.
  • The scope dropdown lists up to 100 recent commits (with relative timestamps) and shows a truncation notice when the limit is reached.
  • ReviewDiffPreviewResult in review.ts gains branchCommits and branchCommitsTruncated fields with backward-compatible defaults for older servers.
  • GitVcsDriverCore gains commit-specific diff generation via git diff-tree --root for root commits and git diff for others, plus NUL-separated git log parsing for branch commit listings.
  • diffPanelStore adds selectCommit and reconcileCommitSelection actions; commit selection auto-reverts to branch view when the selected commit leaves the branch range.

Macroscope summarized 50023e3.


Note

Medium Risk
Touches Git subprocess parsing, review RPC contracts, and diff-panel selection persistence; behavior is well covered by driver and store tests but incorrect commit/base handling could show wrong patches.

Overview
Per-commit review in the Diff pane lets users pick a commit from a Commits submenu (scoped to the current branch vs base comparison) and view that commit’s first-parent patch in the existing diff UI, including file expansion for the new "commit" source kind.

Review API and Git backend gain optional commitSha on diff preview input, branchCommits / branchCommitsTruncated on the result (with backward-compatible decode defaults), and Git logic to list up to 100 commits on baseRef..HEAD, load a single commit diff (parent vs empty tree for root commits), and serve file contents for commit-scoped hunks.

Client state adds a commit diff-panel selection that keeps the branch baseRef, reconciles when the commit drops out of a complete listing, and loads branch preview commits even while viewing a turn or a single commit so the menu stays populated.

Reviewed by Cursor Bugbot for commit 50023e3. Bugbot is set up for automated code reviews on this repo. Configure here.

The Diff pane could only show cumulative branch changes or checkpoint
turns, so there was no way to see what an individual commit changed.

The review diff preview now returns the commits in the active branch
comparison range, and accepts a commit sha to fetch that commit's
first-parent patch on demand. The Diff pane lists those commits in a
Commits submenu beside Turns and renders the selected one through the
existing diff renderer, file expansion, and view controls. Commit
selections keep the chosen comparison base and fall back to Branch
changes when history is rewritten.

Closes pingdotgg#5881.
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f543d9e0-c745-4ded-a134-b9cee518f485

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 11, 2026
Comment thread apps/server/src/vcs/GitVcsDriverCore.ts Outdated
Comment thread docs/user/source-control.md Outdated
Comment thread apps/web/src/diffPanelStore.ts Outdated
@pranav100000
pranav100000 marked this pull request as ready for review August 11, 2026 07:53
Comment thread apps/web/src/components/DiffPanel.tsx
Comment thread apps/web/src/components/DiffPanel.tsx Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 290469294f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/contracts/src/review.ts Outdated
Comment on lines +68 to +69
branchCommits: Schema.Array(ReviewBranchCommit),
branchCommitsTruncated: Schema.Boolean,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Make the new preview fields optional for older servers

When an updated hosted web or mobile client connects to an older remote T3 server, that server's review.getDiffPreview response lacks these newly required properties, so the RPC success schema rejects the entire response and the existing diff pane stops working. Keep these fields optional on the wire and treat them as []/false in clients so independently updated remote clients remain compatible.

AGENTS.md reference: AGENTS.md:L19-L21

Useful? React with 👍 / 👎.

import * as Order from "effect/Order";

export type ReviewSectionKind = "turn" | "working-tree" | "branch-range";
export type ReviewSectionKind = "turn" | ReviewDiffPreviewSourceKind;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add commit selection to the mobile review surface

This widens mobile's section kind to include commit, but useReviewSections.ts:35-40 still requests only the ordinary preview and review-section-menu.ts:3-20 exposes only working-tree, branch, and turn sections. Consequently mobile users cannot list or request any of the per-commit diffs added here, even though mobile already has the corresponding review surface; wire branchCommits and commit requests into that menu rather than changing only its type.

AGENTS.md reference: AGENTS.md:L65-L72

Useful? React with 👍 / 👎.

Comment on lines +610 to +615
{branchCommits.length === 0 ? (
<DropdownMenuItem disabled>
{branchDiffPreview.isPending
? "Loading commits..."
: "No commits in the branch range."}
</DropdownMenuItem>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Load commits while a turn diff is selected

When the current selection is a turn, the branch-preview query is disabled by the selectedTurnId === null condition at lines 257-268, leaving branchCommits empty. This new submenu therefore reports “No commits in the branch range” and offers no commit actions until the user first switches to Branch changes and reopens the menu, even when the branch has commits; keep the lightweight branch/commit-list query available for this menu state.

Useful? React with 👍 / 👎.

@macroscopeapp

macroscopeapp Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

1 blocking correctness issue found. This PR introduces a new per-commit diff view feature spanning server, web, and contracts layers with significant new logic. Multiple unresolved review comments identify potential bugs around base ref handling and backward compatibility concerns.

You can customize Macroscope's approvability policy. Learn more.

The new preview fields are required on the wire, so an updated client
talking to an older server fails to decode the whole diff preview. They
now carry decoding defaults: an older server that omits them decodes to
an empty, untruncated commit list.

The Commits submenu read the branch preview, which only ran when no turn
was selected, so the menu was empty from any turn scope. The branch
preview now runs for every selection.

The branch commit listing capped output bytes without allowing
truncation, so an oversized listing raised instead of truncating and
degraded to no commits at all. It now truncates, and byte truncation
reports through branchCommitsTruncated.

Reconciling a commit selection cleared it whenever the sha was missing
from the listing, including when the listing was capped, empty, or had
not loaded. Only a complete, non-empty listing now proves a commit left
the range.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
);
// Runs for every selection: the scope menu lists this preview's commits even while a
// turn or a single commit is being viewed.
const primaryBranchDiffPreview = useEnvironmentQuery(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 High components/DiffPanel.tsx:259

When a user picks a custom branch base ref and then switches to a turn, primaryBranchDiffPreview now always runs but uses selectedBaseRef, which is null for turn selections. The Commits submenu is therefore populated from the automatic range, not the user's custom range. Selecting one of those commits restores the custom baseRef, and reconcileCommitSelection immediately rejects that commit (it is not in the custom-range listing) and bounces back to branch view — so the user cannot select a commit that was shown to them. Consider preserving the last-selected baseRef when switching to a turn so the commit list stays scoped to the custom range.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/DiffPanel.tsx around line 259:

When a user picks a custom branch base ref and then switches to a turn, `primaryBranchDiffPreview` now always runs but uses `selectedBaseRef`, which is `null` for turn selections. The Commits submenu is therefore populated from the automatic range, not the user's custom range. Selecting one of those commits restores the custom `baseRef`, and `reconcileCommitSelection` immediately rejects that commit (it is not in the custom-range listing) and bounces back to branch view — so the user cannot select a commit that was shown to them. Consider preserving the last-selected `baseRef` when switching to a turn so the commit list stays scoped to the custom range.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 50023e3eee

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 259 to +260
const primaryBranchDiffPreview = useEnvironmentQuery(
selectedTurnId === null && activeThread && activeCwd
activeThread && activeCwd

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid loading full branch patches for turn views

When the pane opens or restores with a turn selected, this unconditional query runs review.getDiffPreview in addition to the checkpoint-diff query merely to populate the Commits submenu. In GitVcsDriverCore, that RPC computes and returns the tracked and untracked working-tree patches plus the branch-range patch before returning commit metadata, so a closed submenu can add substantial Git work and WebSocket traffic—especially for remote clients and repositories with many untracked files. Use a metadata-only request or load the commit list lazily instead of running the full preview for every selection.

AGENTS.md reference: AGENTS.md:L15-L17

Useful? React with 👍 / 👎.

Comment on lines +190 to +193
const selectedBaseRef =
diffSelection.kind === "branch" || diffSelection.kind === "commit"
? diffSelection.baseRef
: null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the remembered base when listing commits

After a user chooses a custom base and switches to a turn or the working tree, this sets selectedBaseRef to null, so the Commits submenu is populated from the automatically resolved range. However, selectCommit restores the custom value from branchBaseRefByThreadKey; clicking an item therefore immediately changes the range used for reconciliation, which can bounce back to Branch changes when that SHA is absent from the custom range or display an out-of-range commit when the custom range is empty. The menu query and stored commit selection need to use the same remembered base.

Useful? React with 👍 / 👎.

Comment on lines +148 to +151
previous?.kind !== "commit" ||
!listIsComplete ||
availableCommitShas.length === 0 ||
availableCommitShas.includes(previous.commitSha)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reconcile a selected commit against an empty completed range

When a rebase/reset removes all branch-range commits, or the user changes the base to the current head, a successful current-server preview returns a complete empty branchCommits list. This length guard preserves the old selection indefinitely; because the commit object commonly remains reachable through the reflog, its preview can continue showing a commit that is no longer in the selected range while the submenu says there are no commits. Distinguish unavailable/legacy listings from an authoritative empty result and fall back to the branch view for the latter.

Useful? React with 👍 / 👎.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 50023e3. Configure here.

// turn or a single commit is being viewed.
const primaryBranchDiffPreview = useEnvironmentQuery(
selectedTurnId === null && activeThread && activeCwd
activeThread && activeCwd

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commits list ignores persisted base

Medium Severity

The branch preview now runs while a turn is selected so the Commits menu stays populated, but selectedBaseRef is still null for turn selections. That fetches commits against the automatic base instead of the persisted branch comparison in branchBaseRefByThreadKey. With a custom base, the menu can list the wrong commits; picking one restores the custom base via selectCommit, then reconcileCommitSelection can immediately fall back to branch changes.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 50023e3. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Add per-commit views to the Diff pane

1 participant