fix(vcs): list files in the Compare tool window and open each diff in the editor (#2611)

The Compare tool window rendered the side-by-side diff inline next to the file
tree; in a sidebar the file names were cut off and the diff was a few pixels
tall. It now lists only the changed files, and double-click or Show Diff
opens the diff in an editor tab. Swap Sides and Jump to Source are
unchanged; the Changes Between dialog keeps its inline diff.
This commit is contained in:
l0ng-ai
2026-11-11 08:26:29 +08:00
committed by GitHub
parent daa7f96f7e
commit e593d07405
4 changed files with 20 additions and 1 deletions
+4 -1
View File
@@ -17,6 +17,7 @@ export function ComparisonTree<F>({
openOnActivate = false,
getColor,
onOpen,
inlineDiff = true,
}: {
tree: FileTreeNode<F>[];
current: F | null;
@@ -27,10 +28,12 @@ export function ComparisonTree<F>({
openOnActivate?: boolean;
getColor?: (entry: F) => string | undefined;
onOpen?: () => void;
/** Show the selected file's diff beside the tree; off where there is no room (a sidebar). */
inlineDiff?: boolean;
}) {
const [selected, setSelected] = useState<ReadonlySet<string>>(new Set());
const [expanded, setExpanded] = useState<ReadonlySet<string> | null>(null);
const data = current && diffFor(current);
const data = inlineDiff && current && diffFor(current);
const input = data ? diffInput(data) : null;
return (
<div className={`${styles.comparison} ${input ? styles.comparisonWithDiff : ""}`}>
@@ -114,6 +114,16 @@ describe("CompareToolWindow", () => {
expect(mocks.openFile).toHaveBeenCalledWith("/workspace/client/src/app.ts", { focus: true });
});
it("lists files without an inline diff and opens a file's diff in the editor", async () => {
mocks.openDiff.mockResolvedValue(undefined);
render(<CompareToolWindow />);
const file = await screen.findByText("app.ts");
fireEvent.mouseDown(file, { button: 0 });
expect(screen.queryByTestId("diff")).toBeNull();
fireEvent.doubleClick(file);
expect(mocks.openDiff).toHaveBeenLastCalledWith(expect.objectContaining({ path: "/workspace/client/src/app.ts" }));
});
it("has no Jump to Source for a file deleted from the working tree", async () => {
render(<CompareToolWindow />);
fireEvent.mouseDown(await screen.findByText("old.ts"), { button: 0 });
+1
View File
@@ -93,6 +93,7 @@ export function CompareToolWindow() {
from={target.from}
to={target.to}
native
listOnly
swapped={swapped}
onSelect={select}
onShowDiff={showDiff}
+5
View File
@@ -602,6 +602,7 @@ export function ChangesBetweenDialog({
onShowDiff,
swapped = false,
onSelect,
listOnly = false,
}: {
from: Revision;
to: Revision | null;
@@ -615,6 +616,8 @@ export function ChangesBetweenDialog({
swapped?: boolean;
/** Reports the selected file (the Compare tool window's Jump to Source / Swap Sides). */
onSelect?: (file: ComparisonFile | null) => void;
/** Files only, each diff opening in the editor (the Compare tool window's narrow sidebar). */
listOnly?: boolean;
}) {
const [root] = useState(currentRepoRoot);
const [repo] = useState(currentRepo);
@@ -741,6 +744,8 @@ export function ChangesBetweenDialog({
diffFor={diffFor}
getColor={(f) => KIND_COLOR[f.kind === "untracked" ? "added" : f.kind]}
ariaLabel="Changed files"
inlineDiff={!listOnly}
openOnActivate={listOnly}
renderDetails={(n) =>
n.file ? (
<>