How to Exclude Log Files from Version Control Without Ignoring All .log Files
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.
# 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.
# 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.loganywhere in the repository.!logs/important.log— Overrides the previous rule for this exact file path, marking it for tracking.!keep-logs/— Un-ignores thekeep-logs/directory itself, which is required before its contents can be considered.keep-logs/**— Ensures all files insidekeep-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, the template ignores all log files but explicitly preserves the placeholder file on line 17:
! /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 template on line 33 applies a strict blanket rule:
*.log
This configuration contains no negation because typical WordPress deployments should never track log files. Similarly, VisualStudio.gitignore (line 120) and Unity.gitignore (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*.logrule 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.gitignorefor placeholder file preservation andWordPress.gitignorefor 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →