From 7ac09bbd6aaa478ff6454a830175abef2a5546cd Mon Sep 17 00:00:00 2001 From: d-kimsuon Date: Thu, 23 Oct 2025 03:26:31 +0900 Subject: [PATCH] fix: Git Diff View works in subdirectories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove explicit .git directory checks from executeGitCommand functions. Git automatically searches parent directories for .git, making these checks unnecessary and preventing subdirectory execution. Changes: - src/server/core/git/functions/utils.ts: Remove .git existence check - src/server/core/git/services/GitService.ts: Remove .git existence check - src/server/core/git/functions/getDiff.test.ts: Add subdirectory test case Fixes #25 ๐Ÿค– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/server/core/git/functions/getDiff.test.ts | 38 +++++++++++++++++++ src/server/core/git/functions/utils.ts | 13 +------ src/server/core/git/services/GitService.ts | 6 +-- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/server/core/git/functions/getDiff.test.ts b/src/server/core/git/functions/getDiff.test.ts index 43b3dea..23140ad 100644 --- a/src/server/core/git/functions/getDiff.test.ts +++ b/src/server/core/git/functions/getDiff.test.ts @@ -367,6 +367,44 @@ index abc123..abc123 100644`; }); describe("ใ‚จใƒƒใ‚ธใ‚ฑใƒผใ‚น", () => { + it("ใ‚ตใƒ–ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใ‹ใ‚‰ๅฎŸ่กŒใ—ใฆใ‚‚ๅ‹•ไฝœใ™ใ‚‹", async () => { + const mockCwd = "/test/repo/subdirectory"; + const fromRef = "base:main"; + const toRef = "compare:feature"; + + const mockNumstatOutput = `3\t1\tsrc/file.ts`; + const mockDiffOutput = `diff --git a/src/file.ts b/src/file.ts +index abc123..def456 100644 +--- a/src/file.ts ++++ b/src/file.ts +@@ -1,2 +1,3 @@ + content`; + + vi.mocked(utils.executeGitCommand) + .mockResolvedValueOnce({ + success: true, + data: mockNumstatOutput, + }) + .mockResolvedValueOnce({ + success: true, + data: mockDiffOutput, + }); + + const result = await getDiff(mockCwd, fromRef, toRef); + + expect(result.success).toBe(true); + if (result.success) { + expect(result.data.files).toHaveLength(1); + expect(result.data.files[0]?.filePath).toBe("src/file.ts"); + } + + // Verify that git commands are executed in the subdirectory + expect(utils.executeGitCommand).toHaveBeenCalledWith( + ["diff", "--numstat", "main", "feature"], + mockCwd, + ); + }); + it("็‰นๆฎŠๆ–‡ๅญ—ใ‚’ๅซใ‚€ใƒ•ใ‚กใ‚คใƒซๅใ‚’ๅ‡ฆ็†ใงใใ‚‹", async () => { const mockCwd = "/test/repo"; const fromRef = "base:main"; diff --git a/src/server/core/git/functions/utils.ts b/src/server/core/git/functions/utils.ts index e090564..087564a 100644 --- a/src/server/core/git/functions/utils.ts +++ b/src/server/core/git/functions/utils.ts @@ -15,7 +15,7 @@ export async function executeGitCommand( cwd: string, ): Promise> { try { - // Check if the directory exists and contains a git repository + // Check if the directory exists if (!existsSync(cwd)) { return { success: false, @@ -27,16 +27,7 @@ export async function executeGitCommand( }; } - if (!existsSync(resolve(cwd, ".git"))) { - return { - success: false, - error: { - code: "NOT_A_REPOSITORY", - message: `Not a git repository: ${cwd}`, - command: `git ${args.join(" ")}`, - }, - }; - } + // Git will search parent directories for .git, so we don't need to check explicitly const { stdout } = await execFileAsync("git", args, { cwd, diff --git a/src/server/core/git/services/GitService.ts b/src/server/core/git/services/GitService.ts index f6f72d8..0248b5a 100644 --- a/src/server/core/git/services/GitService.ts +++ b/src/server/core/git/services/GitService.ts @@ -33,11 +33,7 @@ const LayerImpl = Effect.gen(function* () { ); } - if (!(yield* fs.exists(path.resolve(absoluteCwd, ".git")))) { - return yield* Effect.fail( - new NotARepositoryError({ cwd: absoluteCwd }), - ); - } + // Git will search parent directories for .git, so we don't need to check explicitly const command = Command.make("git", ...args).pipe( Command.workingDirectory(absoluteCwd),