How to Ignore Changes to Tracked Files with `git skip-worktree`
TL;DR
If you want Git to ignore changes to a file that’s already committed (tracked), use git update-index --skip-worktree. .gitignore and .git/info/exclude only work for untracked files.
Problem: .git/info/exclude can’t ignore changes to tracked files
When you want to ignore files only in your local environment on a per-project basis, you might think .git/info/exclude is the right tool. But there’s a catch.
Both .git/info/exclude and .gitignore are meant to ignore untracked files. They have no effect on files that are already committed (tracked).
So if you customize a configuration file that’s already in the repository and want Git to ignore your local changes, these won’t help.
Solution: Use --skip-worktree
To ignore local changes to a file that’s already tracked, use git update-index --skip-worktree:
# Ignore local changes
git update-index --skip-worktree path/to/file
# Revert it
git update-index --no-skip-worktree path/to/file
What --skip-worktree is
This tells Git: “I’ll modify this file locally, but don’t track those changes.” It’s useful when you intentionally want Git to ignore modifications, such as local customization of config files.
Common use cases
- Customizing development environment config files (
config/local.py,.env.local, etc.) - Personal tweaks to IDE settings files
- Local-only debug settings
Check which files are configured
# List files with --skip-worktree enabled
git ls-files -v | grep '^S'
# If you only want the path names
git ls-files -v | grep '^S' | cut -c 3-
Meaning of git ls-files -v output
S= skip-worktree is setH= normal tracked fileh= assume-unchanged is set
A handy alias
git config --global alias.skipped "ls-files -v | grep '^S'"
# Usage
git skipped
--skip-worktree vs --assume-unchanged
Git also has a similar option, --assume-unchanged, but it’s meant for a different purpose:
| Option | Purpose | Stability |
|---|---|---|
--skip-worktree |
Intentionally ignore changes | Stable (persists unless you explicitly unset it) |
--assume-unchanged |
Performance optimization | Unstable (can be reset by Git operations) |
Recommendation: If you intentionally want to ignore local changes, --skip-worktree is the more reliable choice.
Caveats
Conflicts with remote updates
If the same file is updated remotely and you try to git pull, you may get conflicts. In that case:
# Temporarily disable skip-worktree
git update-index --no-skip-worktree path/to/file
# Stash your local changes
git stash
# Pull from remote
git pull
# Restore your changes if needed
git stash pop
# Enable skip-worktree again
git update-index --skip-worktree path/to/file
Notes for team development
Since --skip-worktree is a local setting, you should use .gitignore for files the whole team should ignore.
Summary
- Ignore untracked files:
.gitignoreor.git/info/exclude - Ignore changes to tracked files:
git update-index --skip-worktree - Check settings:
git ls-files -v | grep '^S'
It’s a subtle but useful technique that lets you develop without worrying about local, environment-specific config tweaks.
We look forward to discussing your development needs.