# Gitignore
## Precedence and Negation
### How Git evaluates ignore rules
**Precedence (high to low):**
1. Command-line excludes
2. `.gitignore` files from repository root down to file's directory (closer directories override higher ones)
3. `.git/info/exclude`
4. Global ignore file
**Within the same precedence level:** Last matching pattern wins.
### Negation with `!`
A pattern starting with `!` negates a previous ignore match (re-includes the path).
**Example:**
```gitignore
.env* # Ignore all .env* files
!.env.example # But keep .env.example
!*.gpg # But keep all .gpg files
```
**Question:** Will `.env.gpg` be ignored?
**Answer:** No - `.env.gpg` will **not** be ignored.
**Why:**
- `.env*` matches `.env.gpg` and ignores it
- `!*.gpg` (later line) re-includes any `*.gpg` file, including `.env.gpg`
- **Last matching pattern wins**, so final state is **not ignored**
### Important caveats
1. **Cannot re-include from ignored parent directory**
- If `.env.gpg` is inside an ignored directory (e.g., `secrets/`), a `!` rule cannot re-include it
- Git doesn't descend into ignored directories
2. **Already tracked files**
- `.gitignore` only affects untracked files
- If `.env.gpg` is already tracked, it stays tracked until `git rm --cached .env.gpg`
### Force ignore a negated file
If you want `.env.gpg` to be ignored despite `!*.gpg`:
**Option 1: Add more specific ignore after the negation**
```gitignore
.env*
!*.gpg
.env.gpg # Last match wins; ignores just this one
```
**Option 2: Swap order (if appropriate)**
```gitignore
!*.gpg
.env* # Last match wins; .env.gpg will be ignored
```
### Check which rule applies
```bash
git check-ignore -v .env.gpg
```
Prints the rule and file that decides the outcome.
## Are multiple `.gitignore`s frowned on?
[source](https://stackoverflow.com/questions/3305869/are-multiple-gitignores-frowned-on)
> I can think of at least two situations where you would want to have multiple `.gitignore` files in different (sub)directories.
>
> - Different directories have different types of file to ignore. For example the `.gitignore` in the top directory of your project ignores generated programs, while `Documentation/.gitignore` ignores generated documentation.
>
> - Ignore given files only in given (sub)directory (you can use `/sub/foo` in `.gitignore`, though).
>
>
> Please remember that patterns in [`.gitignore`](http://git-scm.com/docs/gitignore "gitignore(5) Manual Page - Specifies intentionally untracked files to ignore") file apply recursively to the (sub)directory the file is in and all its subdirectories, unless pattern contains '/' (so e.g. pattern `name` applies to any file named `name` in given directory and all its subdirectories, while `/name` applies to file with this name only in given directory).