How to make .gitignore ignore everything except a few files?

To configure a .gitignore file to ignore all files and directories except for specific ones, use exclusion patterns with ! after a global ignore. Here’s a step-by-step guide:

1. Ignore Everything

Start by ignoring all files and directories:

# .gitignore
*

2. Whitelist Directories

Unignore directories you want to keep (Git tracks files, not empty directories):

!src/       # Keep the 'src' directory (but not its contents yet)
!docs/      # Keep the 'docs' directory

3. Whitelist Specific Files

Unignore files you want to track:

!README.md    # Keep README.md in the root
!*.txt        # Keep all .txt files in any directory (use with caution)
!/config.yml  # Keep config.yml in the root

4. Whitelist Files Inside Directories

For files inside directories (e.g., src/main.c):

# Allow files inside 'src/'
src/*       # First, ignore everything in 'src/'
!src/main.c # Then unignore 'src/main.c'
!src/utils/ # Unignore the 'utils/' subdirectory

5. Example: Ignore Everything Except Specific Files/Dirs

*
# Keep these files/dirs
!.gitignore
!README.md
!src/
!docs/

# Unignore files inside 'src/'
src/*
!src/main.c
!src/utils/

# Unignore files inside 'src/utils/'
src/utils/*
!src/utils/helper.py

Key Rules:

  1. Order Matters: .gitignore is processed top-to-bottom. Define global ignores first, then exceptions.
  2. Directories:
  • Use / to target directories (e.g., src/).
  • Git doesn’t track empty directories. Add a .gitkeep file if needed.
  1. Patterns:
  • *: Matches any file/directory.
  • !: Negates a pattern (unignores).
  • **/: Matches nested directories (e.g., **/*.txt keeps all .txt files anywhere).

Common Use Cases

Case 1: Keep only .txt files in the root

*
!*.txt

Case 2: Keep only src/ and docs/

*
!src/
!docs/

Case 3: Keep specific files in subdirectories

*
!src/
src/*
!src/main.c
!src/README.md

Verify Your .gitignore

Check ignored files with:

git status --ignored

This ensures your rules work as expected!

Leave a Reply

Your email address will not be published. Required fields are marked *