DEV Community

Cover image for Not Just .gitignore: Four Methods to Ignore Files in Git and How to Use Them
tumf
tumf

Posted on • Originally published at blog.tumf.dev

Not Just .gitignore: Four Methods to Ignore Files in Git and How to Use Them

Originally published on 2026-01-10
Original article (Japanese): .gitignore だけじゃない: Git ファイル無視の4つの方法と使い分け

While .gitignore is a well-known method for ignoring files in Git, there are actually three other methods available. Scenarios such as wanting to change environment-dependent configuration files locally or wanting to skip differential checks for large SDKs cannot be resolved with .gitignore alone.

In this article, we will compare the four methods of ignoring files in Git and organize their usage based on different situations.

Conclusion First: Flowchart for Choosing the Right Method

The following flowchart helps you select the optimal method based on your situation.

flowchart TD
    A[Want to ignore a file] --> B{Is the file<br/>under Git management?}
    B -->|Untracked| C{Do you want to<br/>ignore it for the whole team?}
    B -->|Tracked| D{What is the purpose?}

    C -->|Yes| E[.gitignore]
    C -->|No| F[.git/info/exclude]

    D -->|Performance<br/>optimization| G[--assume-unchanged]
    D -->|Protect local<br/>settings changes| H[--skip-worktree]

    E --> E1[Commit to<br/>shared repository]
    F --> F1[Personal local<br/>no impact on others]
    G --> G1[Skip change checks<br/>flag is volatile]
    H --> H1[Protect local changes<br/>flag is persistent]

    style E fill:#90EE90
    style F fill:#87CEEB
    style G fill:#FFB6C1
    style H fill:#FFD700
Enter fullscreen mode Exit fullscreen mode

Overview of the Four Methods

1. .gitignore (Untracked Files, Team Shared)

Usage Scenario: Files that should be ignored by the entire team, such as build artifacts, log files, and dependency directories.

Features:

  • Committed to the repository (shared by everyone)
  • Only applies to untracked files
  • Has no effect on files already under Git management

Example:

# Build artifacts
dist/
*.pyc
__pycache__/

# Dependencies
node_modules/
venv/

# Environment variable file
.env
Enter fullscreen mode Exit fullscreen mode

Official Documentation: gitignore Documentation

2. .git/info/exclude (Untracked Files, Personal Local)

Usage Scenario: Ignore settings for personal working files, editor configurations, and local scripts that you don't want to affect others.

Features:

  • Not committed to the repository (personal local)
  • Uses the same syntax as .gitignore
  • Not included when cloning

Example:

# Edit the .git/info/exclude file
echo "*.swp" >> .git/info/exclude
echo ".vscode/" >> .git/info/exclude
echo "my-local-notes.md" >> .git/info/exclude
Enter fullscreen mode Exit fullscreen mode

Use Cases: Temporary files from editors, personal notes, local development scripts.

3. --assume-unchanged (Tracked Files, Performance Optimization)

Usage Scenario: Files that are costly to check for changes, such as large SDKs or libraries.

Features:

  • Aimed at performance optimization
  • Skips checks by assuming the file has not changed
  • The flag is volatile (reset automatically on git pull)
  • Not suitable for managing configuration files

Command:

# Set the flag
git update-index --assume-unchanged path/to/file

# Check the flag (h = assumed-unchanged)
git ls-files -v | grep "^h"

# Remove the flag
git update-index --no-assume-unchanged path/to/file
Enter fullscreen mode Exit fullscreen mode

Note: The official Git documentation explicitly states not to use it for ignoring configuration files.

4. --skip-worktree (Tracked Files, Local Settings Change)

Usage Scenario: Files that need local changes, such as environment-dependent configuration files, that you don't want to reflect upstream.

Features:

  • Aimed at protecting local changes
  • The flag is persistent (not reset on git pull)
  • Changes are protected even with git reset --hard

Command:

# Set the flag
git update-index --skip-worktree path/to/config.json

# Check the flag (S = skip-worktree)
git ls-files -v | grep "^S"

# Remove the flag
git update-index --no-skip-worktree path/to/config.json
Enter fullscreen mode Exit fullscreen mode

Typical Use Case:

# A production configuration file exists in the repository
# You want to use a different configuration for local development
git update-index --skip-worktree config/database.yml
vim config/database.yml  # Edit for local use
git status  # Not shown as a change
Enter fullscreen mode Exit fullscreen mode

Differences Between assume-unchanged and skip-worktree

These two methods are similar but have important behavioral differences.

Operation assume-unchanged skip-worktree
git pull (changes upstream) Flag is reset Flag is retained
git stash Local changes discarded Stash fails (changes are protected)
git reset --hard Flag is reset File is protected
Branch Switching May cause errors May cause errors

From the official Git documentation:

Users often try to use the assume-unchanged and skip-worktree bits to tell Git to ignore changes to files that are tracked. This does not work as expected, since Git may still check working tree files against the index when performing certain operations. In general, Git does not provide a way to ignore changes to tracked files, so alternate solutions are recommended.

In other words, neither is a proper method for managing configuration files.

Recommended Configuration File Management by Git

The official documentation (since Git 2.25.1) recommends the following alternatives:

Method 1: Template File Approach

# Repository structure
config.json.example    # Committed to the repository
config.json            # Ignored by .gitignore

# Setup steps
cp config.json.example config.json
vim config.json  # Edit for local use
Enter fullscreen mode Exit fullscreen mode

.gitignore:

config.json
Enter fullscreen mode Exit fullscreen mode

Method 2: Automated Generation via Script

#!/bin/bash
# setup-config.sh
# Generate config.json by replacing environment variables from the template

envsubst < config.json.template > config.json
Enter fullscreen mode Exit fullscreen mode

config.json.template:

{
  "api_url": "${API_URL}",
  "debug": "${DEBUG_MODE}"
}
Enter fullscreen mode Exit fullscreen mode

This method allows you to manage local settings using environment variables.

Method 3: Smudge/Clean Filter (For Advanced Users)

Using a content filter driver, you can automatically expand templates at checkout.

Details will be covered in a separate article.

Example: Managing Environment-Dependent File Patterns

Files that have settings replaced by environment variables at build time or files that differ between development and production environments can be managed as follows:

❌ Incorrect Method

# This is not recommended by the official documentation
git update-index --assume-unchanged config/api-config.js
git update-index --skip-worktree src/constants.js
Enter fullscreen mode Exit fullscreen mode

Issues:

  • Unexpected behavior may occur on git pull
  • Confusion arises when different methods are used by team members
  • Forgetting to set flags can lead to configuration files being overwritten

✅ Correct Method

Pattern 1: Template File + Build Script

# build.sh
envsubst < config/api-config.js.template > config/api-config.js
npm run build
Enter fullscreen mode Exit fullscreen mode

.gitignore:

config/api-config.js
Enter fullscreen mode Exit fullscreen mode

Benefits:

  • Managed via environment variables, making it easy to integrate with CI/CD
  • Templates can be version-controlled
  • Consistent methods can be used across the team

Pattern 2: Switching Between Environment-Specific Files

config/
  ├── config.development.json   # For development environment
  ├── config.staging.json       # For staging environment
  └── config.production.json     # For production environment
Enter fullscreen mode Exit fullscreen mode

Switching at build time using environment variables:

cp config/config.${NODE_ENV}.json config/config.json
Enter fullscreen mode Exit fullscreen mode

Benefits:

  • Explicit management of settings for each environment
  • Simple environment switching

Conclusion

There are four methods for ignoring files in Git, but it is important to use them appropriately based on your objectives:

Method Target Sharing Scope Purpose
.gitignore Untracked Team-wide Build artifacts, dependencies
.git/info/exclude Untracked Personal Editor settings, personal notes
--assume-unchanged Tracked Personal Performance optimization (not recommended)
--skip-worktree Tracked Personal Local settings change (not recommended)

Key Points:

  • --assume-unchanged and --skip-worktree are not proper methods for managing configuration files
  • The official recommendation is the "template file + .gitignore" approach
  • If you must use one, --skip-worktree is safer (local changes are protected)

If you're struggling with configuration file management, consider starting with the "template file approach."

Reference Links

Top comments (0)