From aee131dfe69fccb4149d1249638df17db5784477 Mon Sep 17 00:00:00 2001 From: imabdulazeez Date: Fri, 1 May 2026 16:55:57 +0530 Subject: [PATCH 1/3] fix(server): walk parent dirs in isGitRepository so subdirectories of a git repo are detected Previously isGitRepository only checked cwd/.git, so opening t3code at a sub-package of a monorepo (e.g. apps/server) was treated as non-git, silently disabling checkpoints and the diff panel. Walk up to the filesystem root to match git's own behavior. Fixes #2441 --- apps/server/src/git/Utils.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/apps/server/src/git/Utils.ts b/apps/server/src/git/Utils.ts index 15015e8cda..4b428851fb 100644 --- a/apps/server/src/git/Utils.ts +++ b/apps/server/src/git/Utils.ts @@ -8,10 +8,24 @@ import { Schema } from "effect"; import { TextGenerationError } from "@t3tools/contracts"; import { existsSync } from "node:fs"; -import { join } from "node:path"; +import { dirname, join, parse } from "node:path"; export function isGitRepository(cwd: string): boolean { - return existsSync(join(cwd, ".git")); + const root = parse(cwd).root; + let current = cwd; + while (true) { + if (existsSync(join(current, ".git"))) { + return true; + } + if (current === root) { + return false; + } + const parent = dirname(current); + if (parent === current) { + return false; + } + current = parent; + } } /** Convert an Effect Schema to a flat JSON Schema object, inlining `$defs` when present. */ From 352a5043c135948449180c350877d7e76c2715d0 Mon Sep 17 00:00:00 2001 From: imabdulazeez Date: Fri, 1 May 2026 17:53:19 +0530 Subject: [PATCH 2/3] refactor(server): simplify isGitRepository per review Apply review suggestion: collapse the parent-walk into a single while loop using the dirname-equals-self termination check, and drop the redundant parse(cwd).root guard. Behavior is unchanged for every cwd the codebase actually passes in (always a sub-path of the repo). --- apps/server/src/git/Utils.ts | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/apps/server/src/git/Utils.ts b/apps/server/src/git/Utils.ts index 4b428851fb..012ab0d266 100644 --- a/apps/server/src/git/Utils.ts +++ b/apps/server/src/git/Utils.ts @@ -8,24 +8,13 @@ import { Schema } from "effect"; import { TextGenerationError } from "@t3tools/contracts"; import { existsSync } from "node:fs"; -import { dirname, join, parse } from "node:path"; - -export function isGitRepository(cwd: string): boolean { - const root = parse(cwd).root; - let current = cwd; - while (true) { - if (existsSync(join(current, ".git"))) { - return true; - } - if (current === root) { - return false; - } - const parent = dirname(current); - if (parent === current) { - return false; - } - current = parent; +import { dirname, join } from "node:path"; + +export function isGitRepository(current: string): boolean { + while (current !== (current = dirname(current))) { + if (existsSync(join(current, ".git"))) return true; } + return false; } /** Convert an Effect Schema to a flat JSON Schema object, inlining `$defs` when present. */ From 594fc8dd4cdbf177a07c6e91730eeae3b959497c Mon Sep 17 00:00:00 2001 From: imabdulazeez Date: Fri, 1 May 2026 17:57:50 +0530 Subject: [PATCH 3/3] fix(server): check input dir in isGitRepository before walking parents The previous while-loop form advanced current to its parent in the loop condition before the existsSync check ran, so the input directory was never tested. Calling isGitRepository on a path that itself contains .git returned false. Switch to do...while so the check runs before the advance, without duplicating the existsSync call. --- apps/server/src/git/Utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/server/src/git/Utils.ts b/apps/server/src/git/Utils.ts index 012ab0d266..139229a48e 100644 --- a/apps/server/src/git/Utils.ts +++ b/apps/server/src/git/Utils.ts @@ -11,9 +11,9 @@ import { existsSync } from "node:fs"; import { dirname, join } from "node:path"; export function isGitRepository(current: string): boolean { - while (current !== (current = dirname(current))) { + do { if (existsSync(join(current, ".git"))) return true; - } + } while (current !== (current = dirname(current))); return false; }