diff --git a/packages/core/src/git.ts b/packages/core/src/git.ts index eea11c95f7..8ac4ed203b 100644 --- a/packages/core/src/git.ts +++ b/packages/core/src/git.ts @@ -189,16 +189,14 @@ const layer = Layer.effect( if (!dotgit) return undefined const cwd = path.dirname(dotgit) - const git = run(cwd, proc) - const topLevel = yield* git(["rev-parse", "--show-toplevel"]) - const gitDir = yield* git(["rev-parse", "--git-dir"]) - const commonDir = yield* git(["rev-parse", "--git-common-dir"]) - if (gitDir.exitCode !== 0 || commonDir.exitCode !== 0) return undefined + const result = yield* run(cwd, proc)(["rev-parse", "--git-dir", "--git-common-dir", "--show-toplevel"]) + const [gitDir, commonDir, topLevel] = result.text.split(/\r?\n/) + if (!gitDir || !commonDir) return undefined return new Repository({ - worktree: AbsolutePath.make(topLevel.exitCode === 0 ? resolvePath(cwd, topLevel.text) : cwd), - gitDirectory: AbsolutePath.make(resolvePath(cwd, gitDir.text)), - commonDirectory: AbsolutePath.make(resolvePath(cwd, commonDir.text)), + worktree: AbsolutePath.make(topLevel ? resolvePath(cwd, topLevel) : cwd), + gitDirectory: AbsolutePath.make(resolvePath(cwd, gitDir)), + commonDirectory: AbsolutePath.make(resolvePath(cwd, commonDir)), }) }) diff --git a/packages/core/test/git.test.ts b/packages/core/test/git.test.ts index 7441ff83db..d4d80fd732 100644 --- a/packages/core/test/git.test.ts +++ b/packages/core/test/git.test.ts @@ -13,6 +13,26 @@ import { testEffect } from "./lib/effect" const it = testEffect(LayerNode.compile(Git.node)) describe("Git", () => { + it.live("discovers repository metadata without a work tree", () => + Effect.gen(function* () { + const root = yield* Effect.acquireRelease( + Effect.promise(() => tmpdir()), + (dir) => Effect.promise(() => dir[Symbol.asyncDispose]()), + ) + yield* Effect.promise(async () => { + await initRepo(root.path) + await $`git config core.bare true`.cwd(root.path).quiet() + }) + const directory = AbsolutePath.make(yield* Effect.promise(() => fs.realpath(root.path))) + const git = yield* Git.Service + const repository = yield* git.repo.discover(directory) + + expect(repository?.worktree).toBe(directory) + expect(repository?.gitDirectory).toBe(AbsolutePath.make(path.join(directory, ".git"))) + expect(repository?.commonDirectory).toBe(repository?.gitDirectory) + }), + ) + it.live("clones a remote and reads checkout metadata", () => withRemote((fixture) => Effect.gen(function* () {