You’ve been working on a feature branch, made some local config changes you don’t want to commit, and now you need to switch branches to hotfix a production bug. Git throws an error: “Your local changes would be overwritten by checkout.”
You have two options: commit your half-finished work or lose your changes. Neither sounds appealing.
This is exactly the problem skip-worktree was designed to solve.
The Scenario
You have a file (typically a config file, environment settings, or local overrides) that you modify frequently but never want to commit to the repository. When you try to switch branches, Git sees the modification and blocks you.
There’s a better way than stashing, committing, or manually re-applying changes.
Solution 1: skip-worktree (Best for Permanent Local Overrides)
The skip-worktree flag tells Git to pretend a file is unchanged—even when you’ve modified it. Git will ignore the file during branch switches, merges, and pulls.
Mark a file as skipped:
git update-index --skip-worktree <file-path>
Resume normal tracking (when you do want to commit):
git update-index --no-skip-worktree <file-path>
See all skipped files:
git ls-files -v | grep '^S'
The S prefix indicates the file is flagged with skip-worktree.
When to Use skip-worktree
This approach works best for files you permanently modify locally and never intend to commit:
- Local database configuration
- IDE settings or editor overrides
- Environment-specific
.envfiles - Development-only configurations
The flag persists across branch switches and even survives git pull operations.
Solution 2: git stash (Best for Temporary Changes)
If you only need to temporarily clear changes to switch branches—not permanently hide them—git stash is cleaner and more direct.
Stash a specific file:
git stash push <file-path>
Switch branches normally:
git checkout <other-branch>
Return to your original branch and restore changes:
git checkout <original-branch>
git stash pop
The stash pops the changes back exactly as you left them.
skip-worktree vs assume-unchanged: What’s the Difference?
Git has another similar flag: assume-unchanged. Here’s how they compare:
| Feature | skip-worktree | assume-unchanged |
|---|---|---|
| Best Use Case | Local config files you modify but don’t commit | Performance optimization for large files |
| Persistence | Survives branch switches and pulls | Can be reset by Git operations |
| Status Output | Hidden from git status | Hidden from git status |
Use skip-worktree for files you want to persistently keep modified locally. Use assume-unchanged only when Git’s performance checks on large, rarely-changing files are slowing you down.
One Important Caveat
If the branch you’re switching to doesn’t contain the file you’re protecting with skip-worktree, Git may still throw an error. In that case, you’ll need to either stash the file temporarily or commit it before switching branches.
Pick the Right Tool
- skip-worktree: Permanent local overrides (config files, never-commit files)
- git stash: Temporary branch switching with the intent to return and commit later
Stop manually re-applying config changes. Let Git handle the complexity for you.
Tags: #Git #VersionControl #DeveloperWorkflow #Tips #SoftwareEngineering