Skip to content

fix(desktop): correct renamed file diffs and reset expanded commits on workspace switch#327

Merged
Kitenite merged 2 commits intomainfrom
cognitive-catfish-c31a56
Dec 12, 2025
Merged

fix(desktop): correct renamed file diffs and reset expanded commits on workspace switch#327
Kitenite merged 2 commits intomainfrom
cognitive-catfish-c31a56

Conversation

@Kitenite
Copy link
Copy Markdown
Collaborator

@Kitenite Kitenite commented Dec 12, 2025

Summary

  • Fix renamed files showing blank/incorrect originals in diff viewer by passing oldPath to getFileContents and using it for the "original" side lookup
  • Reset expandedCommits state when workspace changes to prevent querying old commit hashes against the new worktree

Test plan

  • Rename a file and stage it, verify the diff shows the correct original content
  • Create a commit with a renamed file, verify the committed diff shows correctly
  • Switch workspaces while commits are expanded, verify no errors from stale commit queries

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Improved tracking and display support for files that have been renamed or moved in version control
  • Bug Fixes

    • Fixed an issue where stale data could persist when switching between different workspaces or projects
  • Style

    • Enhanced the visual layout and spacing of the changes view interface for improved usability

✏️ Tip: You can customize this high-level summary in your review settings.

…n workspace switch

- Fix renamed files showing blank/incorrect originals in diff viewer by passing
  oldPath to getFileContents and using it for the "original" side lookup
- Reset expandedCommits state when workspace changes to prevent querying old
  commit hashes against the new worktree

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Dec 12, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
website Ready Ready Preview Comment Dec 12, 2025 2:24am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 12, 2025

Walkthrough

This PR enhances the file content retrieval workflow by adding an optional oldPath parameter to the getFileContents TRPC procedure. The backend wires this parameter through all git operation branches, the frontend passes it during queries, and a cleanup effect resets commit expansion state when the worktree changes.

Changes

Cohort / File(s) Summary
Backend file path resolution
apps/desktop/src/lib/trpc/routers/changes/changes.ts
Added optional oldPath parameter to getFileContents input schema; introduced originalPath variable derived from oldPath or original filePath; updated all git show calls across against-main, committed, staged, and unstaged branches to use originalPath instead of input.filePath
Frontend query integration
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/ChangesContent.tsx
Updated getFileContents.useQuery call to pass oldPath in payload; restructured main content layout with nested rounded container, tertiary background styling, and reorganized positioning of FileHeader, DiffToolbar, and DiffViewer components
Worktree state management
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx
Added useEffect hook that resets expandedCommits set when worktreePath changes to prevent stale commit hash queries

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

  • Backend path resolution: Review all four git operation branches (against-main, committed, staged, unstaged) to verify originalPath is correctly applied in each case, especially the committed branch which uses commitHash
  • UI layout restructuring: Verify visual consistency and spacing of the new nested container structure and that the changes don't affect component functionality
  • Worktree effect logic: Confirm the useEffect dependency and behavior prevent stale queries without causing unnecessary resets or race conditions

Poem

🐰 A path once taken, now with an old name,
Through git's many branches, our file queries came,
When worktrees do shift, the memory clears,
Fresh commits await, no stale data fears!
With oldPath in hand, the changes align, 🌟

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the main objectives and test plan but is missing required template sections like 'Related Issues', 'Type of Change', 'Screenshots', and other structured fields. Fill in all required template sections including Related Issues, Type of Change (Bug fix), Testing details, and Additional Notes to match the repository's description template.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main changes: fixing renamed file diffs by handling the oldPath parameter and resetting expanded commits on workspace switch.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch cognitive-catfish-c31a56

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 and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Dec 12, 2025

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

  • ✅ Neon database branch

Thank you for your contribution! 🎉

@Kitenite Kitenite merged commit 786441d into main Dec 12, 2025
7 of 8 checks passed
@Kitenite Kitenite deleted the cognitive-catfish-c31a56 branch December 12, 2025 02:25
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (4)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx (1)

2-2: useEffect import is only needed because of the reset effect—consider removing the effect entirely (see below).

apps/desktop/src/lib/trpc/routers/changes/changes.ts (2)

226-236: oldPath addition to the tRPC input is the right surface-area change for rename diffs.
One minor hardening: use nullish coalescing so an accidental empty string doesn’t override filePath.

- oldPath: z.string().optional(),
+ oldPath: z.string().optional(),

(Then use ?? below.)


239-316: originalPath wiring fixes renamed-file “original side” retrieval across categories.
Suggestion: switch to ?? to avoid treating "" as intentional, and keep behavior consistent.

- const originalPath = input.oldPath || input.filePath;
+ const originalPath = input.oldPath ?? input.filePath;

Also worth double-checking (manual test) the “initial commit” case where ${commitHash}^ doesn’t exist; your try/catch makes it safe, but it’s easy to regress later.

apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/ChangesContent.tsx (1)

36-48: Passing oldPath through to getFileContents is the correct plumbing for rename diffs.
Optional: if you want the payload cleaner, you can omit the key when undefined (not required).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5ff08a2 and 3666842.

📒 Files selected for processing (3)
  • apps/desktop/src/lib/trpc/routers/changes/changes.ts (5 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/ChangesContent.tsx (2 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx (2 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
apps/desktop/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

For Electron interprocess communication, ALWAYS use tRPC as defined in src/lib/trpc

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx
  • apps/desktop/src/lib/trpc/routers/changes/changes.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/ChangesContent.tsx
apps/desktop/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.{ts,tsx}: Please use alias as defined in tsconfig.json when possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx
  • apps/desktop/src/lib/trpc/routers/changes/changes.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/ChangesContent.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Maintain type safety and avoid using any unless absolutely necessary in TypeScript code

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx
  • apps/desktop/src/lib/trpc/routers/changes/changes.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/ChangesContent.tsx
**/components/**/[A-Z]*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Use one folder per component with structure ComponentName/ComponentName.tsx + index.ts barrel export

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/ChangesContent.tsx
apps/desktop/src/renderer/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Never import Node.js modules in renderer process or shared code - only in src/main/

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/ChangesContent.tsx
apps/desktop/src/lib/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Never import Node.js modules like node:fs, node:path, node:os in src/lib/electron-router-dom.ts or similar shared code

Files:

  • apps/desktop/src/lib/trpc/routers/changes/changes.ts
🧠 Learnings (2)
📚 Learning: 2025-12-08T23:32:32.232Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-08T23:32:32.232Z
Learning: Applies to apps/desktop/src/main/lib/*{workspace,worktree}-*.ts : Use git worktree-based workspace management in the desktop app through workspace-manager.ts and worktree-manager.ts

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx
  • apps/desktop/src/lib/trpc/routers/changes/changes.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/ChangesContent.tsx
📚 Learning: 2025-11-24T21:33:13.267Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.267Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build
🔇 Additional comments (1)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/ChangesContent.tsx (1)

111-125: Layout refactor looks safe (no behavioral coupling to diff rendering).
Just ensure overflow-hidden + inner flex-1 doesn’t clip tooltips/menus from DiffViewer if it renders portals/popovers inside the container.

Comment on lines +54 to +60
// Reset expanded commits when workspace changes to avoid querying
// old commit hashes against the new worktree
// biome-ignore lint/correctness/useExhaustiveDependencies: intentionally resets on worktreePath change
useEffect(() => {
setExpandedCommits(new Set());
}, [worktreePath]);

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.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx

Repository: superset-sh/superset

Length of output: 8037


🏁 Script executed:

# Search for all usages of expandedCommits in the file
rg -n "expandedCommits" apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx

Repository: superset-sh/superset

Length of output: 300


Resetting expandedCommits in useEffect allows stale getCommitFiles queries to be registered against the new worktree.

When worktreePath changes, the component re-renders with trpc.useQueries(...) (line 61-68) still using the old expandedCommits state. Only after the render completes does the effect run to reset the state. This means queries for previous commit hashes execute against the new worktree before being cleared.

A more robust approach is to scope expansion state by worktreePath so switching workspaces naturally starts with an empty set without needing an effect:

- import { useEffect, useState } from "react";
+ import { useState } from "react";
  ...
- const [expandedCommits, setExpandedCommits] = useState<Set<string>>(
-   new Set(),
- );
-
- // Reset expanded commits when workspace changes to avoid querying
- // old commit hashes against the new worktree
- // biome-ignore lint/correctness/useExhaustiveDependencies: intentionally resets on worktreePath change
- useEffect(() => {
-   setExpandedCommits(new Set());
- }, [worktreePath]);
+ const [expandedCommitsByWorktree, setExpandedCommitsByWorktree] = useState<
+   Record<string, Set<string>>
+ >({});
+
+ const expandedCommits = worktreePath
+   ? (expandedCommitsByWorktree[worktreePath] ?? new Set<string>())
+   : new Set<string>();
  ...
  const handleCommitToggle = (hash: string) => {
-   setExpandedCommits((prev) => {
-     const next = new Set(prev);
-     if (next.has(hash)) next.delete(hash);
-     else next.add(hash);
-     return next;
-   });
+   if (!worktreePath) return;
+   setExpandedCommitsByWorktree((prev) => {
+     const current = prev[worktreePath] ?? new Set<string>();
+     const next = new Set(current);
+     if (next.has(hash)) next.delete(hash);
+     else next.add(hash);
+     return { ...prev, [worktreePath]: next };
+   });
  };

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx
around lines 54 to 60, the effect-based reset of expandedCommits runs after
render which allows stale getCommitFiles queries for previous commits to fire
against a new worktree; instead, make the expansion state scoped to worktreePath
(e.g. track expanded commits per-worktree via an object/Map keyed by
worktreePath or include worktreePath in the state shape) so the initial render
uses an empty expansion set for a new worktree; update all accesses and setters
to read/write the per-worktree entry and initialize useState with the entry for
the current worktreePath (removing the post-render useEffect reset).

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant