Files
paseo/packages/app/src/git/diff-order.ts
T
Christoph Leiter 2755596b9f fix(app): align the scrolling diff order with the Changes tree (#3913)
The Changes view listed the same files in two different orders. The
tree rail put directories before files at each level of the path.
The scrolling diff compared the full path byte by byte. A root file
such as .gitlab-ci.yml therefore opened the diff, but sat below every
directory in the tree. Scrolling the diff did not walk the tree from
top to bottom.

Two sorts caused this. sortTree in git/diff-tree.ts sorted the tree.
compareCheckoutDiffPaths in git/diff-order.ts sorted the flat list at
ingest.

The tree is now the only ordering authority.
orderCheckoutDiffFiles builds the tree and reads the file sequence
back out of it. compareCheckoutDiffPaths is deleted, so the two
surfaces can no longer disagree.

The daemon keeps its own whole-path sort, so daemons that are not
updated also get this fix. Commit diffs keep the order that git
gives them, because that panel shows no tree rail.
2026-08-27 08:00:25 +00:00

19 lines
936 B
TypeScript

import type { ParsedDiffFile } from "@getpaseo/protocol/messages";
import { buildDiffTree, flattenDiffTree } from "@/git/diff-tree";
// The Changes tree is the single ordering authority: `sortTree` (diff-tree.ts)
// ranks directories before files within a level, then compares names. Surfaces
// that render the flat file list — the scrolling diff — derive their order from
// the tree here instead of reimplementing the rule, so the two cannot disagree.
export function orderCheckoutDiffFiles(files: ParsedDiffFile[]): ParsedDiffFile[] {
if (files.length < 2) {
return files;
}
// Path compression only merges display rows for single-child directory
// chains, so it is skipped; the collapsed set is empty because the flat list
// always carries every file, whatever the rail has collapsed.
return flattenDiffTree(buildDiffTree(files), new Set()).flatMap((row) =>
row.kind === "file" ? [row.file] : [],
);
}