fix(git-ui): prevent large commit diffs from freezing the history tab

Harden commit diff loading/rendering so opening a very large commit no longer hangs
the browser tab.

Problem
- commit history diff viewer rendered every diff line as a React node
- very large commits could create thousands of nodes and lock the UI thread
- backend always returned full commit patch payloads, amplifying frontend pressure

Backend safeguards
- add `COMMIT_DIFF_CHARACTER_LIMIT` (500,000 chars) in git routes
- update GET `/api/git/commit-diff` to truncate oversized diff payloads
- include `isTruncated` flag in response for observability/future UI handling
- append truncation marker text when server-side limit is applied

Frontend safeguards
- update `GitDiffViewer` to use bounded preview rendering:
  - character cap: 200,000
  - line cap: 1,500
- move diff preprocessing into `useMemo` for stable, one-pass preview computation
- show a clear "Large diff preview" notice when truncation is active

Impact
- commit diff expansion remains responsive even for high-change commits
- UI still shows useful diff content while avoiding tab lockups
- changes apply to shared diff viewer usage and improve resilience broadly

Validation
- `node --check server/routes/git.js`
- `npm run typecheck`
- `npx eslint src/components/git-panel/view/shared/GitDiffViewer.tsx`
This commit is contained in:
Haileyesus
2026-03-10 23:19:52 +03:00
parent 68787e01fc
commit a780cb6523
2 changed files with 43 additions and 4 deletions

View File

@@ -7,6 +7,7 @@ import { queryClaudeSDK } from '../claude-sdk.js';
import { spawnCursor } from '../cursor-cli.js';
const router = express.Router();
const COMMIT_DIFF_CHARACTER_LIMIT = 500_000;
function spawnAsync(command, args, options = {}) {
return new Promise((resolve, reject) => {
@@ -769,8 +770,13 @@ router.get('/commit-diff', async (req, res) => {
'git', ['show', commit],
{ cwd: projectPath }
);
res.json({ diff: stdout });
const isTruncated = stdout.length > COMMIT_DIFF_CHARACTER_LIMIT;
const diff = isTruncated
? `${stdout.slice(0, COMMIT_DIFF_CHARACTER_LIMIT)}\n\n... Diff truncated to keep the UI responsive ...`
: stdout;
res.json({ diff, isTruncated });
} catch (error) {
console.error('Git commit diff error:', error);
res.json({ error: error.message });