All guidesCheck your own repo
On this page

Git question

Is my .env file committed to git, and what do I do if it is?

By Ohad Krispin, founder of VibeRaven · LinkedIn

Run git ls-files to see which env files git tracks now and git log --all to see every commit that ever touched one; any hit means the values in it are in your history, so rotate those keys with each provider first, then stop tracking the file with git rm --cached and add it to .gitignore. GitHub says revoking or rotating the secret comes first, because rewriting history does not remove the copies in clones and forks.

Next step in your repo: run npx -y viberaven@1.6.12 check. It reports secrets_in_repo when an env-style file such as .env or .env.local sits in the folder and .gitignore does not cover it; it checks names only, not contents or git history, so run the git ls-files and git log lines below too.

Paste this to your agent

Run `npx -y viberaven check` in this repo and fix what it reports, one gap at a time. Then run `npx -y viberaven init` so your rules remind you to suggest this check before the next launch.

The check runs locally, with no sign-in and no API key. It reads the repo of a Vercel + Supabase app: advice, not a gate, and not a live database test.

Repository check

Check this in your repo

Find env files .gitignore does not cover

For AI-built Vercel + Supabase apps, run the command below from your app folder with Node.js 20 or newer. It walks the folder, skips what .gitignore covers, and reports secrets_in_repo for each env-style file name left, such as .env, .env.local or .env.production; .env.example does not count. A file that is ignored now but was committed before is not reported, because it reads .gitignore, not git history, and it never reads the values.

It is a repository check, not a live database test: it cannot tell whether a key was pushed or used. It is advice, not a gate, and it exits with code 1 when it finds a blocker.

npx -y viberaven@1.6.12 check

What it printed on a fixture repo

On 2026-10-28 we ran it on a small Vite fixture repo made for this page, not a customer repo, with placeholder values in .env and .env.local and a .gitignore that lists only node_modules and dist. The output is below, with the folder shortened to ~/app. .env.local is named as private-like, so the finding is a blocker and the exit code was 1.

$ npx -y viberaven@1.6.12 check

viberaven check · ~/app

🔴 Private-credential-like filenames need review  (secrets_in_repo)
   This filename-only check found files not covered by .gitignore (.env, .env.local). Contents and Git tracking were not checked by this finding. Private-credential-like filenames requiring review: .env.local. Credential content remains unverified.

Verdict: ❌ 1 blocker, 0 warnings · score 80
Fix: viberaven fix · Details: ~/app/.viberaven/agent-tasklist.md

Check tracking and history

The first line lists env files git tracks now. The second lists every commit, on every branch, that added, changed or deleted one, so a file removed later still shows. The third says whether a file is ignored and by which rule.

# env files git tracks now
git ls-files -- '.env*' '*/.env*'

# every commit that ever touched one, on every branch
git log --all --oneline --name-status -- '.env*' '*/.env*'

# is it ignored, and by which line of .gitignore
git check-ignore -v .env.local

Rotate the keys first

GitHub says the first step is to revoke or rotate the secret, and that this may be all you need. Rotate every value the file held with its provider: a new Supabase secret key, a new Stripe secret key, new API keys, then update them in Vercel and redeploy. For the Supabase server key, see how to rotate a leaked service role key.

Stop tracking the file

git rm --cached removes the file from git and keeps it on your disk. Ignore every env file and keep the example tracked.

git rm --cached .env .env.local
printf '.env*\n!.env.example\n' >> .gitignore
git add .gitignore
git commit -m "Stop tracking env files"

Rewrite history only if you must

GitHub's guide rewrites history with git-filter-repo and a force push, and warns that the old commits can still be reached in other people's clones, in forks and in pull requests. That is why rotation comes first: after it, the old values in history are dead.

Checklist

If an env file was committed

  1. 01Run the git ls-files and git log lines above.
  2. 02Write down every key the committed file held, in every version git log shows.
  3. 03Rotate each key with its provider and update it in Vercel and Supabase.
  4. 04Untrack the file with git rm --cached and add .env* to .gitignore, keeping .env.example.
  5. 05Keep only placeholder values in .env.example, never real ones.

Related

Sources

Official docs behind this checklist

FAQ

FAQ for builders before launch

Is a committed .env.example a problem?

Not when it holds placeholders. It is meant to be tracked so the next clone knows which names to set. Check that nobody pasted a real value into it.

The repo is private. Do I still need to rotate?

If only you can read it and nothing was pushed elsewhere, the risk is lower, but a private repo can become public, gain collaborators or be cloned to a laptop that is lost. Rotating once costs less than finding out later.