CLAUDE LABJP
FORK — Claude Code 2.1.212 changes what /fork does: it copies your conversation into a new background session with its own row in claude agents, so you can keep working. The old in-session subagent is now /subtaskLIMITS — WebSearch calls are now capped at 200 per session by default, and subagent spawns get the same 200 ceiling, so a runaway search or delegation loop stops on its ownMCPBG — MCP tool calls running past two minutes now move to the background automatically, keeping the session usable. Tune the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MSPLANFIX — Fixed plan mode auto-running file-modifying Bash commands such as touch and rm without a permission prompt or an SDK canUseTool callbackSONNET5 — Claude Sonnet 5 is running on introductory pricing of $2 per million input tokens and $10 per million output. After August 31 it moves to $3 and $15IPO — Bankers are reportedly lining up investor meetings for Anthropic ahead of a possible public listing as soon as OctoberFORK — Claude Code 2.1.212 changes what /fork does: it copies your conversation into a new background session with its own row in claude agents, so you can keep working. The old in-session subagent is now /subtaskLIMITS — WebSearch calls are now capped at 200 per session by default, and subagent spawns get the same 200 ceiling, so a runaway search or delegation loop stops on its ownMCPBG — MCP tool calls running past two minutes now move to the background automatically, keeping the session usable. Tune the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MSPLANFIX — Fixed plan mode auto-running file-modifying Bash commands such as touch and rm without a permission prompt or an SDK canUseTool callbackSONNET5 — Claude Sonnet 5 is running on introductory pricing of $2 per million input tokens and $10 per million output. After August 31 it moves to $3 and $15IPO — Bankers are reportedly lining up investor meetings for Anthropic ahead of a possible public listing as soon as October
Articles/Claude Code
Claude Code/2026-04-30Intermediate

Why Claude Code Skips .gitignore Files in Search — and How to Pull Them in When You Need Them

When .env.example or dist/ won't show up in Claude Code's Glob and Grep, .gitignore is the reason. Here's why it happens, plus three concrete ways through it: the Read tool, --no-ignore flags, and selective gitignore overrides.

claude-code129troubleshooting87gitignoreglob2grep2

You ask Claude Code to look at .env.example and it tells you the file doesn't exist. You ask it to inspect the bundled output in dist/index.js and you get the same answer. Both files are sitting right there on disk. The first time this happened to me, I burned a few minutes retyping the path before I realized what was going on.

This isn't a bug — it's a deliberate default. Claude Code's Glob and Grep tools respect your .gitignore out of the box. Once you understand why, the workaround takes about ten seconds and saves you from a lot of confused back-and-forth.

Why .gitignore Hides Files From Search

Internally, Claude Code's Glob tool behaves like fd and the Grep tool behaves like ripgrep. Both of those tools share the same friendly default: anything Git ignores stays out of the results.

For everyday work, that's exactly what you want. Nobody enjoys grepping through node_modules/ and pulling back ten thousand hits. The whole reason Claude Code stays responsive on large repos is that it skips this noise by default. The same goes for .next/, target/, __pycache__/, and the dozens of other build directories that pile up in modern projects. Filtering them out of search results is what makes "search the codebase" actually feel like searching the codebase rather than searching the filesystem.

But every once in a while the helpfulness backfires. Specifically, when:

  • You want to look at .env.example (and your .gitignore has .env*)
  • You need to inspect the contents of dist/, build/, or .next/
  • You want to read coverage reports under coverage/ or test snapshots
  • You added a folder to .gitignore for personal tinkering and now Claude can't see it

In other words, "I don't want this in Git, but I want Claude to see it for this session" turns out to be a more common situation than you'd expect.

Three Patterns Where This Trips People Up

In practice, the same three scenes account for most of the confusion.

Scene 1: "That file doesn't exist"

You: Read me .env.example
Claude Code: [runs Glob] No file matched at that path.

The file is right there at the project root, but .env* is in .gitignore, so Glob refuses to acknowledge it. The frustrating part is that Claude isn't lying — from its tool's perspective, the file genuinely is invisible.

Scene 2: Reviewing a build artifact

You want to talk about what ended up in dist/index.js after bundling. Claude Code reports that dist/ doesn't exist. Same root cause. This one bites hardest when you're debugging "why is my production bundle so large" and Claude can only see the source files, not the output you actually care about.

Scene 3: Sharing local logs or screenshots

You captured something into screenshots/ or .cache/ for debugging. Claude can't see them, so it gives you generic advice instead of the targeted suggestion you wanted. If you're using a tmp/ or local/ folder as a personal scratchpad and it's gitignored, the same thing applies.

Fix #1: Use the Read Tool With an Explicit Path

There are three ways through this, but the one I reach for first is the simplest: stop asking Claude Code to find the file, and tell it where to look. The Read tool — unlike Glob and Grep — doesn't consult .gitignore at all. If you give it a path, it reads the file.

The phrasing in chat is just:

Read .env.example with the Read tool. Path: ./project-root/.env.example

If you'd rather skip the lookup entirely, paste the contents in yourself:

# Print just the part you want to discuss
cat .env.example | head -50

The trick is to switch from "search and find" to "I already know where it lives." That sidesteps the search-tool layer where .gitignore is enforced. It also tends to produce cleaner conversations, because Claude isn't spending tool calls hunting around — it goes straight to the content.

When you don't actually know the path, find it on the shell first and then hand the result to Claude:

# Plain find ignores .gitignore semantics
find . -name ".env.example" -not -path "*/node_modules/*"
 
# Or list everything Git is currently ignoring
git ls-files --others --exclude-standard

The second command is particularly handy — it prints every file that exists on disk but isn't tracked by Git, which is exactly the set of files that Glob is hiding from you.

A small habit that's saved me time: when I'm unsure whether a path is being ignored, I run git status --ignored first. It splits its output into three buckets — staged, unstaged, and ignored — and the ignored section makes it obvious which files Claude Code's search tools are deliberately skipping. Once you have that list, the decision tree is trivial: if I want the file, I read it directly by path; if I want a class of files, I switch to Bash with --no-ignore.

Fix #2: Run Search Through Bash With --no-ignore

If you want Claude Code itself to do the searching, the cleanest approach is to invoke ripgrep or fd from the Bash tool with --no-ignore:

# Search across all files, ignoring .gitignore (ripgrep)
rg --no-ignore "DATABASE_URL" .
 
# Include hidden files and dot-folders too
rg --no-ignore --hidden "API_KEY" .
 
# Filename search (fd)
fd --no-ignore --hidden "\.env" .

By default, both tools honor .gitignore. The --no-ignore flag turns off that behavior, and --hidden brings dot-folders like .next/ into scope.

One caveat: full-text searching across node_modules/ is brutally slow on any non-trivial project. I usually narrow the scope explicitly:

# "Show me dist and coverage, but skip node_modules"
rg --no-ignore --hidden \
   --glob '!node_modules/**' \
   --glob '!.git/**' \
   "TODO" .

Hand-rolled --glob filters end up faster than letting the tool guess. Whenever Claude Code feels sluggish on a search, an overly broad scope is almost always the reason. A more aggressive variation I've come to like:

# Only look in build outputs, nothing else
rg --no-ignore --hidden \
   --glob 'dist/**' \
   --glob 'build/**' \
   --glob '.next/**' \
   "process.env" .

For more on Bash-tool quirks, see the Claude Code Bash tool error guide.

Fix #3: Patch the .gitignore Itself (Last Resort)

If you really want the standard Glob/Grep tools to recognize a file, you can edit .gitignore. I'd put this last on the list, since changes to that file affect the entire repo and risk committing things you didn't mean to.

If you go this route, the safest option is to use .git/info/exclude for repo-local ignores (it's not committed and only affects your machine) or to selectively un-ignore the specific file you want exposed:

# .gitignore
.env*

# Make .env.example visible again
!.env.example

With this in place, .env.example shows up in Glob/Grep like any other file, and the rest of .env* keeps being ignored. If you only need the change for a debugging session, edit and don't commit. The ! syntax is also useful for whitelisting package-lock.json or pnpm-lock.yaml patterns when you're inside a parent folder that's broadly ignored.

When .gitignore behavior surprises you, git check-ignore -v <path> tells you in one line which rule from which file is hiding the path. It's a small command but it removes most of the guesswork. Worth wiring into your shell aliases if you find yourself diagnosing this often.

What I Actually Use Day to Day

Remembering all of this for every task is unrealistic, so I've settled into a small playbook. Borrow whatever feels useful.

  • Path is known: hand it to the Read tool directly. Covers about 90% of cases
  • Need to search but can scope tight: rg --no-ignore --hidden --glob '!node_modules/**' from Bash
  • A file you'll keep referring to (like .env.example): add a ! exception to .gitignore and commit it
  • Throwaway debug files: park them somewhere that isn't ignored to begin with — for example, don't add tmp/ to .gitignore if you want Claude to read it

One more thing worth adding to the playbook: if you maintain a personal CLAUDE.md for your project, jot down which folders are gitignored on purpose and how you'd like Claude to treat them. A single line like "treat dist/ as read-only — only inspect, never edit" goes a surprisingly long way. Claude Code reads that context on session start and stops asking permission to do things you've already decided about.

For broader configuration questions, the Claude Code settings.json complete guide walks through permissions, env, and the rest of the surface area. If "Claude can't see my environment variables" sounds familiar, the ANTHROPIC_API_KEY troubleshooting guide covers a closely related class of problems.

The next time Claude Code says a file doesn't exist, suspect .gitignore first. To make this stick, run git check-ignore -v .env.example in your own repo today and watch which rule fires. Once the mental model clicks, the tool's behavior stops feeling mysterious — and the back-and-forth that used to happen on every "that file doesn't exist" reply just goes away.

Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

Claude Code2026-05-10
Why Claude Code's Glob and Grep Return Zero Results
When Claude Code's Glob or Grep tool returns no matches even though the files clearly exist, the cause is almost always one of four things. Here's how to triage.
Claude Code2026-06-18
When a Broken settings.json Stops Claude Code From Starting — Safe Mode and How to Split Your Config
How to find which config layer is broken when a settings.json syntax error stops Claude Code from starting, recover in minutes, and structure your settings so an automated pipeline can't quietly break itself.
Claude Code2026-06-10
When git add -A Sweeps Up .bak Backups — The Quiet Trap of In-Place Fix Scripts
How .bak backups left by sed -i and homegrown --fix scripts get silently swept into production by git add -A, why it is so easy to miss, and how scoped adds and .gitignore close the gap for good.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →