# How to Exclude Log Files from Version Control Without Ignoring All .log Files

> Exclude specific log files from version control without ignoring all log files. Use negative patterns in gitignore to selectively include files and directories while ignoring others.

- Repository: [GitHub/gitignore](https://github.com/github/gitignore)
- Tags: how-to-guide
- Published: 2026-02-24

---

**To exclude specific log files from version control while keeping others, combine a general `*.log` ignore rule with negative patterns using the `!` prefix to re-include specific files or directories.**

Managing log files in Git requires balancing repository hygiene with the need to track essential diagnostic data. While the blanket `*.log` pattern keeps development noise out of commits, many projects require sample logs, keep-files, or specific diagnostic outputs to remain versioned. The `github/gitignore` repository demonstrates how to achieve this selective exclusion using pattern negation and careful path specifications.

## How Git Ignore Patterns Handle Log Files

Git’s ignore mechanism evaluates patterns from top to bottom, applying the **last matching rule** it encounters for any given path. When you list `*.log` early in your `.gitignore` file, Git immediately disregards every file ending in `.log` across the entire repository. This behavior is efficient for disposable runtime logs but creates a problem when you need to preserve specific `.log` files for documentation or testing purposes.

The solution leverages **negative patterns**—rules prefixed with an exclamation mark (`!`) that override previous ignore directives. Because Git requires the full relative path from the repository root to match exactly, you must be precise when crafting these exceptions, especially for files nested in subdirectories.

## Selectively Re‑Including Specific Log Files

### The Negation Syntax

Place your general ignore rule first, followed immediately by targeted exceptions. The `!` character tells Git to treat the matched path as a tracked file, even if an earlier pattern would have ignored it.

```gitignore

# Ignore every *.log file by default

*.log

# Re‑include a specific log file (e.g., a sample or important log)

!logs/important.log

```

### Managing Directory Hierarchies

If the file you want to track sits inside a directory that is itself ignored, you must explicitly un-ignore each level of the hierarchy leading to that file. First negate the directory ignore, then negate the file pattern inside it.

```gitignore

# Re‑include all files inside a designated folder

!keep-logs/
keep-logs/**

# If the entire folder was ignored earlier, you must also un‑ignore the folder itself

!keep-logs/

```

**Explanation of the pattern sequence:**

- `*.log` — Ignores any file ending with `.log` anywhere in the repository.
- `!logs/important.log` — Overrides the previous rule for this exact file path, marking it for tracking.
- `!keep-logs/` — Un-ignores the `keep-logs/` directory itself, which is required before its contents can be considered.
- `keep-logs/**` — Ensures all files inside `keep-logs/` are evaluated against subsequent rules, effectively tracking them when combined with the directory un-ignore.

## Industry Patterns from the Gitignore Repository

The `github/gitignore` templates use this exact approach to handle log file edge cases across different technology stacks.

According to the source code in **[Rails.gitignore](https://github.com/github/gitignore/blob/main/Rails.gitignore#L17)**, the template ignores all log files but explicitly preserves the placeholder file on **line 17**:

```gitignore
! /log/.keep

```

This negative pattern ensures the `log/` directory structure survives in empty repositories while still excluding noisy runtime logs like `development.log` or `test.log`.

Conversely, the **[WordPress.gitignore](https://github.com/github/gitignore/blob/main/WordPress.gitignore#L33)** template on **line 33** applies a strict blanket rule:

```gitignore
*.log

```

This configuration contains no negation because typical WordPress deployments should never track log files. Similarly, **[VisualStudio.gitignore](https://github.com/github/gitignore/blob/main/VisualStudio.gitignore#L120)** (line 120) and **[Unity.gitignore](https://github.com/github/gitignore/blob/main/Unity.gitignore#L13)** (line 13) implement the same aggressive `*.log` ignore, reflecting environments where logs are purely build artifacts.

## Summary

- **Use `!` to create exceptions**: Place negative patterns after your general `*.log` rule to re-include specific files.
- **Un-ignore directories first**: If a parent directory is ignored, you must negate that ignore with `!directory/` before negating files inside it.
- **Order matters**: Git applies the last matching rule, so specific exceptions must follow general patterns.
- **Follow established templates**: Reference `Rails.gitignore` for placeholder file preservation and `WordPress.gitignore` for strict exclusion strategies.

## Frequently Asked Questions

### Does the order of patterns matter in .gitignore?

Yes. Git processes the `.gitignore` file sequentially from top to bottom, and the last matching rule takes precedence. If you place `!important.log` before `*.log`, the general ignore will override your specific exception and the file will remain untracked.

### Why do I need to un-ignore a directory before un-ignoring a file inside it?

Git ignores files located within ignored directories regardless of file-specific rules. If you have `logs/` ignored (either explicitly or because it contains only ignored files), you must first add `!logs/` to mark the directory as tracked, then use `!logs/important.log` to track the specific file within it.

### Can I use wildcards in negative patterns to re-include multiple log files?

Yes. You can use patterns like `!logs/*.sample.log` or `!keep-logs/**` to re-include groups of files. However, the negation must still follow the general `*.log` rule, and if any parent directory in the wildcard path is ignored, you must un-ignore that directory first with a separate `!` rule.

### What happens if I negate a pattern but the file still doesn't appear in Git?

Check that the file was not already committed before you added the ignore rule. Git continues to track files that were previously staged or committed even if new ignore patterns would exclude them. Run `git rm --cached <file>` to stop tracking the file while preserving it on disk, then the negation pattern will take effect for future commits.