1. Recognize the failing pattern
In the project root, consider two untracked files: build/keep.txt and build/discard.txt. The following rules exclude build itself, so Git does not traverse it to find keep.txt. The later exception cannot rescue that file.
/build/
!/build/keep.txt 2. Ignore the contents, then keep one file
Replace the previous two rules with the following rules in the root .gitignore. They leave build traversable, ignore its immediate contents and re-include keep.txt. This example keeps one file directly inside build; deeper exceptions also need every parent directory to remain traversable.
Within the same precedence level, the last matching rule wins. Place the exception after the exclusion. Review other matching rules and nested .gitignore files as well.
/build/*
!/build/keep.txt 3. Verify both files
Run these commands from the repository root after creating the two sample files. The verbose output should show !/build/keep.txt for keep.txt and /build/* for discard.txt. A line containing a ! rule means the file is re-included, not ignored.
git check-ignore -v -- build/keep.txt build/discard.txtThe status output should list build/keep.txt as untracked and omit build/discard.txt. If the files are already tracked, use the tracked-files article; ignore rules do not change their index entries.
git status --short --untracked-files=all -- build/ For exact behavior and further details, consult the official references: Git documentation · git check-ignore documentation