Skip to content
Closed
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- Silenced a false-positive `MaxListenersExceededWarning` logged on every request proxied through an external rewrite. [#1697](https://github.com/sourcebot-dev/sourcebot/pull/1697)
- Upgraded `next` to `^16.3.8`. [#1709](https://github.com/sourcebot-dev/sourcebot/pull/1709)
- Fixed implicit directories in the file tree carrying the leaf file's path, which broke folder expansion and the `/api/git/tree` payload. [#1712](https://github.com/sourcebot-dev/sourcebot/pull/1712)

## [5.1.15] - 2026-09-29

Expand Down
17 changes: 17 additions & 0 deletions packages/web/src/features/git/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,20 @@ test('buildFileTree builds a sorted tree from a flat list', () => {
});
});

test('buildFileTree gives implicit directories their own path, not the leaf file path', () => {
const flatList: { type: string, path: string }[] = [
{ type: 'blob', path: 'src/components/buttons/PrimaryButton.tsx' },
];

const tree = buildFileTree(flatList);

const src = tree.children[0];
const components = src.children[0];
const buttons = components.children[0];

expect(src.path).toBe('src');
expect(components.path).toBe('src/components');
expect(buttons.path).toBe('src/components/buttons');
expect(buttons.children[0].path).toBe('src/components/buttons/PrimaryButton.tsx');
});

6 changes: 5 additions & 1 deletion packages/web/src/features/git/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ export const buildFileTree = (flatList: { type: string, path: string }[]): FileT
if (!next) {
next = {
name: part,
path: item.path,
// A node's path is its own location, not the leaf's: an
// implicit directory (`src` for `src/main.ts`) used to get
// the file's path, which broke folder expansion, route
// sync and the /api/git/tree payload.
path: parts.slice(0, i + 1).join('/'),
type: nodeType,
children: [],
};
Expand Down