Overview
Git shows “fatal: pathspec '…' did not match any files” when a path or pattern you provided doesn’t match any tracked or visible files. Typical causes include wrong relative path, shell globbing issues, ignored files, case mismatches, using a path from the wrong directory, or asking Git to operate on files that aren’t in the index or working tree.
This guide gives fast, practical fixes for local development and CI pipelines.
Quickstart: fix it fast
- Ensure you are at the repository root:
- bash:
cd "$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
- bash:
- Check what Git can see:
- Tracked:
git ls-files - Untracked (respect .gitignore):
git ls-files -o --exclude-standard - Status names:
git status --porcelain
- Tracked:
- Correct the path exactly as listed by the above commands. Pay attention to case.
- If you used globs, quote them so Git (not the shell) expands them:
- Example:
git add -- '*.txt'
- Example:
- If files are ignored, either unignore them or force add:
- Check ignore rule:
git check-ignore -v -- path/to/file - Force add:
git add -f path/to/file
- Check ignore rule:
- Disambiguate branch vs path using
--when needed:- Example:
git checkout main -- path/to/file
- Example:
- For commands that require tracked files (e.g.,
checkout --,restore,reset), ensure the file is tracked or specify the correct commit:git add path/to/fileorgit checkout HEAD -- path/to/file
Minimal working example
Reproduce the error and fix it.
# Create a demo repo
mkdir demo && cd demo && git init
mkdir src
printf 'hello\n' > README.md
git add README.md && git commit -m "init"
# 1) Try to restore a file that doesn't exist (pathspec error)
git checkout -- src/app.js
# fatal: pathspec 'src/app.js' did not match any files
# Fix A: create and track the file, then the path exists
printf 'console.log("hi")\n' > src/app.js
git add src/app.js && git commit -m "add app.js"
# Now this works because the file is tracked
git checkout -- src/app.js
# 2) Glob pattern that matches nothing
git add *.txt
# If your shell didn’t expand to any files, Git may treat '*.txt'
# as a pathspec and fail if nothing matches
# Fix B: quote the glob so Git expands it, or ensure files exist
printf 'x\n' > notes.txt
git add -- '*.txt' && git commit -m "add notes.txt"
Common causes and fixes
Wrong relative path
- Cause: Running the command from a subdirectory but providing a path relative to repo root (or vice versa).
- Fix: Change to repo root (
cd "$(git rev-parse --show-toplevel)") or adjust the path to be relative to your current directory.
File is untracked or doesn’t exist at the target commit
- Cause: Commands like
git checkout --,git restore,git resetrequire tracked files or a commit that contains them. - Fix:
git add filefirst, or reference a commit:git checkout HEAD -- fileorgit restore --source=HEAD -- file.
- Cause: Commands like
Ignored by .gitignore
- Cause: The file matches an ignore rule, so Git excludes it.
- Fix: Inspect with
git check-ignore -v -- file. Remove/adjust the ignore rule or force add withgit add -f file.
Shell globbing vs Git pathspec
- Cause: The shell may expand
*.extbefore Git sees it, or pass it literally if it matches nothing, leading to a mismatch. - Fix: Quote patterns for Git expansion:
git add -- '*.ext'. Alternatively, ensure the shell expansion matches files.
- Cause: The shell may expand
Case mismatch
- Cause: On case-sensitive filesystems (Linux),
src/App.jsis notsrc/app.js. - Fix: Use the exact case as shown by
git ls-files. If needed, rename with two-step rename to change case reliably.
- Cause: On case-sensitive filesystems (Linux),
Branch name vs path ambiguity
- Cause:
git checkout somethingmight be interpreted as a branch. - Fix: Use
--to separate branch and path:git checkout main -- path/to/file.
- Cause:
Wrong working directory or sparse checkout
- Cause: Running in the wrong repo, or using sparse-checkout so paths are excluded from the working tree.
- Fix: Confirm repo with
git rev-parse --show-toplevel. For sparse checkouts, include paths:git sparse-checkout add path/.
Quick reference
| Symptom | Likely cause | Fix |
|---|---|---|
| path not found | wrong relative path | go to repo root or adjust path |
| path works in shell but not Git | shell globbing | quote the glob or create files |
| only untracked shows | using checkout/reset on untracked | git add or use HEAD -- path |
| ignored file | .gitignore rules | git check-ignore, git add -f |
| CI step fails | wrong working dir/checkout depth | cd repo, fetch full history if needed |
Step-by-step diagnosis
- Verify repo context:
git rev-parse --is-inside-work-tree
- Move to repo root:
cd "$(git rev-parse --show-toplevel)"
- See what Git knows:
git status --porcelaingit ls-files | sed -n '1,20p'git ls-files -o --exclude-standard | sed -n '1,20p'
- Test the exact path:
- Copy/paste the path from
git statusorgit ls-filesinto your command.
- Copy/paste the path from
- Check ignores:
git check-ignore -v -- path
- Disambiguate branch vs path:
- Add
--between branch and path.
- Add
- If operating on history:
- Ensure the commit contains the file:
git ls-tree -r --name-only <commit> | grep file
- Ensure the commit contains the file:
CI/CD pipeline tips (DevOps)
- Ensure the job runs in the repository root before invoking Git.
- Fetch required history if you reference past commits for paths:
git fetch --depth=0(full history) or a depth that includes needed commits.
- Confirm the workspace matches your path assumptions; if using sparse-checkout, include paths before commands that reference them.
- Print diagnostics on failure:
git status --porcelain,pwd, andls -lato aid debugging.
Pitfalls
- Using paths copied from the OS file manager that differ in case or separators.
- Relying on shell settings like
nullgloborglobstarthat behave differently across environments. - Forgetting
--and unintentionally checking out a branch instead of a file. - Expecting
git reset -- pathto work on never-staged files. - Referencing files that only exist in uncommitted build outputs; commit or adjust the workflow.
Performance notes
- Prefer narrower pathspecs (e.g.,
src/**/*.tsquoted) instead of repo-wide scans. - Avoid huge negated patterns; specify the smallest relevant directories.
- Use quoted globs so Git can evaluate them once, rather than the shell expanding massive argument lists.
- For very large repos, consider sparse-checkout to limit the working set before running path-based commands.
FAQ
Why does quoting
*.txthelp?- It lets Git interpret the pattern as a pathspec, ensuring consistent matching regardless of shell settings.
How do I operate on a file that only exists in a previous commit?
- Use
git checkout <commit> -- pathorgit show <commit>:pathto retrieve its contents.
- Use
Can I make pathspecs anchor to the repo root?
- Prefix with
:(top)magic, e.g.,git add -- ':(top)src/**'.
- Prefix with
How do I find the correct path quickly?
git ls-files | grep -i 'name'to locate the exact tracked path and case.
What if I still get the error in CI only?
- Verify the job’s working directory, fetch depth, and whether the file is generated or ignored during the build.