diff --git a/src/shared/git-worktree/collect-git-diff-stats.test.ts b/src/shared/git-worktree/collect-git-diff-stats.test.ts index 5aab6e25..cc59bfbf 100644 --- a/src/shared/git-worktree/collect-git-diff-stats.test.ts +++ b/src/shared/git-worktree/collect-git-diff-stats.test.ts @@ -7,6 +7,9 @@ const execSyncMock = mock(() => { }) const execFileSyncMock = mock((file: string, args: string[], _opts: { cwd?: string }) => { + if (file === "wc") { + return " 10 new-file.ts\n" + } if (file !== "git") throw new Error(`unexpected file: ${file}`) const subcommand = args[0] @@ -42,7 +45,7 @@ describe("collectGitDiffStats", () => { //#then expect(execSyncMock).not.toHaveBeenCalled() - expect(execFileSyncMock).toHaveBeenCalledTimes(3) + expect(execFileSyncMock).toHaveBeenCalledTimes(4) const [firstCallFile, firstCallArgs, firstCallOpts] = execFileSyncMock.mock .calls[0]! as unknown as [string, string[], { cwd?: string }] @@ -65,6 +68,12 @@ describe("collectGitDiffStats", () => { expect(thirdCallOpts.cwd).toBe(directory) expect(thirdCallArgs.join(" ")).not.toContain(directory) + const [fourthCallFile, fourthCallArgs, fourthCallOpts] = execFileSyncMock.mock + .calls[3]! as unknown as [string, string[], { cwd?: string }] + expect(fourthCallFile).toBe("wc") + expect(fourthCallArgs).toEqual(["-l", "--", "new-file.ts"]) + expect(fourthCallOpts.cwd).toBe(directory) + expect(result).toEqual([ { path: "file.ts", @@ -74,7 +83,7 @@ describe("collectGitDiffStats", () => { }, { path: "new-file.ts", - added: 0, + added: 10, removed: 0, status: "added", }, diff --git a/src/shared/git-worktree/collect-git-diff-stats.ts b/src/shared/git-worktree/collect-git-diff-stats.ts index 546e8bfa..728bd3a0 100644 --- a/src/shared/git-worktree/collect-git-diff-stats.ts +++ b/src/shared/git-worktree/collect-git-diff-stats.ts @@ -30,7 +30,24 @@ export function collectGitDiffStats(directory: string): GitFileStat[] { ? untrackedOutput .split("\n") .filter(Boolean) - .map((filePath) => `0\t0\t${filePath}`) + .map((filePath) => { + try { + const wcOutput = execFileSync("wc", ["-l", "--", filePath], { + cwd: directory, + encoding: "utf-8", + timeout: 5000, + stdio: ["pipe", "pipe", "pipe"], + }).trim() + + const [lineCountToken] = wcOutput.split(/\s+/) + const lineCount = Number(lineCountToken) + if (!Number.isFinite(lineCount)) return `0\t0\t${filePath}` + + return `${lineCount}\t0\t${filePath}` + } catch { + return `0\t0\t${filePath}` + } + }) .join("\n") : ""