## TL;DR
gitleaks defaults to git mode, so running it from a plain directory fails with "fatal: not a git repository". Either run it from inside the checkout or add the no-git flag and point it at the files directly. The scan itself is fine; only the invocation context is wrong.

## Error
```text
gitleaks: fatal: not a git repository
```

## Steps
1. Confirm whether the target is actually a git repo: run `git rev-parse --is-inside-work-tree` in the scan directory. Expected: it prints `true`; if it prints `false` or errors, the directory is not a repo.
2. If it is a repo, change into it (or fix the CI working directory) and rerun `gitleaks detect --source . --verbose`. Expected: the scan starts instead of erroring.
3. If the target is intentionally not a repo (a tarball, a build artifact dir), rerun with no-git mode: `gitleaks detect --source /path/to/dir --no-git --verbose`. Expected: gitleaks walks the files and reports findings or "no leaks found".
4. In CI, make sure the checkout step runs before the scan step and that both share the working directory. Expected: the scan step sees the `.git` directory and runs in git mode.
5. If you only want staged or committed content scanned, run `gitleaks protect --staged --verbose` from the repo root instead. Expected: pre-commit style scan of staged changes.

## When to use
- `gitleaks detect` or `gitleaks protect` fails with "fatal: not a git repository"
- A CI scan step fails because it runs before checkout or in the wrong directory
- Scanning an extracted archive or artifact directory rather than a clone

## When not to use
- gitleaks reports actual findings (that means it worked; rotate the leaked values)
- Errors about config files or rules (different root cause)
- You need history scanning (use git mode from inside the repo)

## Tool compatibility
- gitleaks v8.x (`detect`, `protect`, `--no-git`, `--source` flags as documented)

## Variant phrasings
### gitleaks protect fails outside a repo
Same fix: `gitleaks protect` also assumes a git checkout. Run it from the repo root in pre-commit hooks, or switch to `detect --no-git` for plain directories.

### gitleaks in Docker says not a git repository
The container working directory usually lacks the `.git` mount. Mount the repo (including `.git`) into the container or use `--no-git` against the mounted files.

## Why it happens
gitleaks `detect` opens the source path as a git repository first and shells out to git log for history. When no `.git` directory exists it aborts before scanning anything. The `--no-git` flag switches the engine to a plain filesystem walk, which is what you want for archives and build outputs.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_T6pjd_bDdUpvXDe1ZzBMLw
