From a38fd0003fc3f594f63906bc9b91d455cb9671f9 Mon Sep 17 00:00:00 2001 From: Alejandro Tamayo Date: Fri, 17 Apr 2026 17:17:31 +0200 Subject: [PATCH] fix(windows): normalize git paths to POSIX so sidebar tree view works The sidebar files section rendered as a flat list on Windows because paths occasionally contained backslashes, so the tree builder's `path.split("/")` produced a single segment. Normalize all paths emitted by the git status/diff parsers to forward slashes at the single backend boundary. Git stores paths with "/" on every platform, and Node fs / path.join accept "/" on Windows, so downstream functionality (file reads, diffs, numstat lookups) is unaffected. The renderer's many `split("/")` call sites keep working unchanged on both platforms. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/main/lib/git/utils/parse-status.ts | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/main/lib/git/utils/parse-status.ts b/src/main/lib/git/utils/parse-status.ts index d99870751..401980bee 100644 --- a/src/main/lib/git/utils/parse-status.ts +++ b/src/main/lib/git/utils/parse-status.ts @@ -15,13 +15,20 @@ function mapGitStatus(gitIndex: string, gitWorking: string): FileStatus { return "modified"; } +// Normalize to POSIX separators so the renderer can safely split on "/" +// regardless of platform. Git itself stores paths with "/" on every OS, and +// Node fs / path.join accept "/" on Windows, so functionality is preserved. +function toPosix(p: string): string { + return p.replace(/\\/g, "/"); +} + function toChangedFile( path: string, gitIndex: string, gitWorking: string, ): ChangedFile { return { - path, + path: toPosix(path), status: mapGitStatus(gitIndex, gitWorking), additions: 0, deletions: 0, @@ -47,8 +54,9 @@ export function parseGitStatus( if (index && index !== " " && index !== "?") { staged.push({ - path, - oldPath: file.path !== file.from ? file.from : undefined, + path: toPosix(path), + oldPath: + file.path !== file.from && file.from ? toPosix(file.from) : undefined, status: mapGitStatus(index, " "), additions: 0, deletions: 0, @@ -57,7 +65,7 @@ export function parseGitStatus( if (working && working !== " " && working !== "?") { unstaged.push({ - path, + path: toPosix(path), status: mapGitStatus(" ", working), additions: 0, deletions: 0, @@ -139,12 +147,12 @@ export function parseDiffNumstat( const renameMatch = rawPath.match(/^(.+) => (.+)$/); if (renameMatch) { - const oldPath = renameMatch[1]; - const newPath = renameMatch[2]; + const oldPath = toPosix(renameMatch[1]); + const newPath = toPosix(renameMatch[2]); stats.set(newPath, statEntry); stats.set(oldPath, statEntry); } else { - stats.set(rawPath, statEntry); + stats.set(toPosix(rawPath), statEntry); } } @@ -188,8 +196,8 @@ export function parseNameStatus(nameStatusOutput: string): ChangedFile[] { } files.push({ - path, - oldPath, + path: toPosix(path), + oldPath: oldPath ? toPosix(oldPath) : undefined, status, additions: 0, deletions: 0,