Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions src/main/services/git/GitService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -758,9 +758,17 @@ export class GitService {
}
}
} else {
// Regular commit: use show --name-status
const commitShow = await git.show([trimmedHash, '--name-status', '--pretty=format:%P']);
const lines = commitShow.split('\n').filter((line) => line.trim());
// Regular commit: use diff-tree to list changed files without patch output.
// `--root` ensures the initial commit reports its files too.
const diffTree = await git.raw([
'diff-tree',
'--root',
'--no-commit-id',
'--name-status',
'-r',
trimmedHash,
]);
const lines = diffTree.split('\n').filter((line) => line.trim());

for (const line of lines) {
// Match: status (with optional percentage for R/C) and file path(s)
Expand Down
3 changes: 3 additions & 0 deletions src/renderer/components/source-control/CommitDiffViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ interface CommitDiffViewerProps {
rootPath: string;
fileDiff: FileDiff | null | undefined;
filePath: string | null;
commitHash: string | null;
isActive?: boolean;
isLoading?: boolean;
onPrevFile?: () => void;
Expand All @@ -20,6 +21,7 @@ export function CommitDiffViewer({
rootPath,
fileDiff,
filePath,
commitHash,
isActive = true,
isLoading = false,
onPrevFile,
Expand Down Expand Up @@ -65,6 +67,7 @@ export function CommitDiffViewer({
isActive={isActive}
diff={diffData}
isCommitView
commitHash={commitHash}
onPrevFile={onPrevFile}
onNextFile={onNextFile}
hasPrevFile={hasPrevFile}
Expand Down
34 changes: 30 additions & 4 deletions src/renderer/components/source-control/DiffViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ interface DiffViewerProps {
diff?: FileDiff;
skipFetch?: boolean;
isCommitView?: boolean; // Add flag to indicate commit history view
commitHash?: string | null; // Used to scope Monaco models in commit view
}

export function DiffViewer({
Expand All @@ -128,6 +129,7 @@ export function DiffViewer({
diff: externalDiff,
skipFetch = false,
isCommitView = false,
commitHash = null,
}: DiffViewerProps) {
const sessionId = useActiveSessionId(rootPath);
const { t } = useI18n();
Expand Down Expand Up @@ -726,6 +728,9 @@ export function DiffViewer({
setEditorReady(true);

const currentModel = editor.getModel();
const mountedModels = currentModel
? { original: currentModel.original, modified: currentModel.modified }
: null;
if (currentModel) {
modelsRef.current.original = currentModel.original;
modelsRef.current.modified = currentModel.modified;
Expand Down Expand Up @@ -787,9 +792,16 @@ export function DiffViewer({
for (const d of disposables) {
d.dispose();
}
// Prevent commit-view Monaco models from accumulating in memory.
// We intentionally keep worktree models cached for performance, but commit history
// can generate many unique models (commitHash scoped URIs), so dispose on unmount.
if (isCommitView && mountedModels) {
mountedModels.original?.dispose();
mountedModels.modified?.dispose();
}
};
},
[file?.path, performAutoNavigation]
[file?.path, performAutoNavigation, isCommitView]
);

// Toggle hide unchanged regions
Expand Down Expand Up @@ -1200,11 +1212,25 @@ export function DiffViewer({
<div className="flex-1">
{diff && diff.original != null && diff.modified != null && isThemeReady && (
<DiffEditor
key={`${rootPath}-${file.path}-${file.staged}-${isThemeReady}-${isEditing}`}
key={
isCommitView
? `${rootPath}-${commitHash ?? 'null'}-${file.path}-${file.staged}-${isThemeReady}-${isEditing}`
: `${rootPath}-${file.path}-${file.staged}-${isThemeReady}-${isEditing}`
}
original={diff.original}
modified={isEditing && editedContent !== null ? editedContent : diff.modified}
originalModelPath={toMonacoVirtualUri('inmemory', `original/${rootPath}/${file.path}`)}
modifiedModelPath={toMonacoVirtualUri('inmemory', `modified/${rootPath}/${file.path}`)}
originalModelPath={toMonacoVirtualUri(
'inmemory',
isCommitView && commitHash
? `original/commit/${commitHash}/${rootPath}/${file.path}`
: `original/${rootPath}/${file.path}`
)}
modifiedModelPath={toMonacoVirtualUri(
'inmemory',
isCommitView && commitHash
? `modified/commit/${commitHash}/${rootPath}/${file.path}`
: `modified/${rootPath}/${file.path}`
)}
language={getLanguageFromPath(file.path)}
theme={CUSTOM_THEME_NAME}
onMount={handleEditorMount}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1282,6 +1282,7 @@ export function SourceControlPanel({
rootPath={selectedRepoPath ?? rootPath ?? ''}
fileDiff={commitDiff}
filePath={selectedCommitFile}
commitHash={selectedCommitHash}
isActive={isActive}
isLoading={commitDiffLoading}
onPrevFile={handlePrevCommitFile}
Expand Down
Loading