Ignore a directory except for one subdirectory in Git
Use ordered .gitignore exceptions to keep one nested directory, diagnose matching rules, and distinguish ignored files from already tracked files.
In a repository-root .gitignore, ignore the contents of the parent directory, then add an exception for the child you want to keep:
/main/*
!/main/subfolder2/
This ignores siblings such as main/subfolder1/ and main/subfolder3/, while allowing Git to discover files under main/subfolder2/. It assumes no other matching rule excludes those files.
Keep the parent directory accessible
This pair does not work:
/main/
!/main/subfolder2/
The first rule excludes the parent directory itself. Git does not descend into an excluded directory to find exceptions inside it. Using /main/* leaves main/ accessible while excluding its immediate contents. The leading slash anchors these examples to the directory containing this .gitignore, which is the repository root here.
For a deeper exception, reopen each parent and exclude its unwanted children:
/main/*
!/main/a/
/main/a/*
!/main/a/b/
This keeps files beneath main/a/b/, but excludes other children of main/ and main/a/. See the gitignore pattern rules.
Inspect the rule that matched
git check-ignore -v -- main/subfolder2/file.txt
git check-ignore -v -- main/subfolder1/file.txt
git status --short --ignored --untracked-files=all
Read the pattern in verbose output. A matching pattern that starts with ! is an inclusion exception: output from check-ignore -v does not always mean the file is ignored. No output can mean no rule matched; tracked files are also normally omitted by this diagnostic.
For an already tracked path, inspect the applicable ignore rules without consulting the index:
git check-ignore -v --no-index -- main/subfolder2/file.txt
This is a diagnostic option, not an instruction to stop tracking the file. The check-ignore reference explains its output format.
Handle files Git already tracks
Ignore rules govern untracked files. Adding a tracked file to .gitignore does not remove it from the index or stop future changes from appearing in diffs.
To deliberately stop tracking a file while keeping your local copy:
git rm --cached -- main/subfolder1/file.txt
git diff --cached
Review and commit the staged removal together with the ignore rule. This changes the repository for collaborators too; it is not a private local setting. For a whole directory, git rm -r --cached -- DIRECTORY applies the same operation recursively, so inspect the staged result carefully.
FAQ
Why does an exception still fail?
Check whether an ancestor is excluded, whether a later rule in the same file or a rule in a deeper .gitignore overrides your exception, and whether the directory contains a file. Git does not store empty directories. A placeholder file is sufficient; .gitkeep is only a naming convention, with no special Git behavior.
Can I ignore all log files except one?
Yes. Put the exception after the general rule:
*.log
!important.log
This allows files named important.log wherever these rules apply, provided their parent directories remain accessible. Use !/important.log to limit the exception to the .gitignore directory itself.
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan