{"id":"0b6539a97e39783c","repo":"vitest-dev/vitest","slug":"vitest-git-not-found","errorCode":"VITEST_GIT_NOT_FOUND","errorMessage":"Could not find Git root. Have you initialized git with `git init`?","messagePattern":"Could not find Git root\\. Have you initialized git with `git init`\\?","errorType":"exception","errorClass":"GitNotFoundError","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/node/vcs/git.ts","lineNumber":31,"sourceCode":"    try {\n      result = await x('git', args, { nodeOptions: { cwd: this.root } })\n    }\n    catch (e: any) {\n      e.message = e.stderr\n\n      throw e\n    }\n\n    return result.stdout\n      .split('\\n')\n      .filter(s => s !== '')\n      .map(changedPath => resolve(this.root, changedPath))\n  }\n\n  async findChangedFiles(options: VCSProviderOptions): Promise<string[]> {\n    const root = this.root || await this.getRoot(options.root)\n    if (!root) {\n      throw new GitNotFoundError()\n    }\n\n    this.root = root\n\n    const changedSince = options.changedSince\n    if (typeof changedSince === 'string') {\n      const [committed, staged, unstaged] = await Promise.all([\n        this.getFilesSince(changedSince),\n        this.getStagedFiles(),\n        this.getUnstagedFiles(),\n      ])\n      return [...committed, ...staged, ...unstaged]\n    }\n    const [staged, unstaged] = await Promise.all([\n      this.getStagedFiles(),\n      this.getUnstagedFiles(),\n    ])\n    return [...staged, ...unstaged]","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/vitest/src/node/vcs/git.ts#L13-L49","documentation":"Thrown as `GitNotFoundError` (code `VITEST_GIT_NOT_FOUND`) from `GitVCSProvider.findChangedFiles` (git.ts:31) when `getRoot(cwd)` returns null, meaning `git rev-parse --show-cdup` failed or returned nothing. This provider powers the `--changed` / `-w` (watch changed files) features; without a git repository root it cannot compute changed files, so it aborts with a hint to initialize git.","triggerScenarios":"Running `vitest --changed` or `vitest -w` inside a directory that is not inside any git work tree; running in a fresh project before `git init`; running in a container/CI checkout where `.git` was stripped out; git not installed so `x('git', ...)` throws and `getRoot` swallows it returning null.","commonSituations":"New project not yet `git init`'d; archived/extracted source without `.git`; minimal Docker images lacking git; CI that does a shallow copy without the `.git` directory.","solutions":["Run `git init` (and make at least one commit) in the project root.","Ensure `git` is installed and on PATH in the running environment.","Avoid `--changed`/`-w` flags in environments without a git work tree; run the full suite instead.","If in CI, make sure the checkout step preserves the `.git` directory."],"exampleFix":"# before\nvitest --changed   # in a non-git directory\n# after\ngit init && git add -A && git commit -m init\nvitest --changed","handlingStrategy":"validation","validationCode":"import { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\nlet dir = process.cwd()\nwhile (dir !== resolve(dir, '..')) {\n  if (existsSync(resolve(dir, '.git'))) break\n  dir = resolve(dir, '..')\n}\nif (!existsSync(resolve(dir, '.git'))) throw new Error('Not inside a git work tree')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run `git init` and make an initial commit before using `--changed`.","Ensure git is installed in CI/Docker images that use changed-file features.","Preserve `.git` in CI checkouts that compute changed files."],"tags":["vcs","git","changed-files","environment"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}