Setup & configAlways fixable

Keep local changes to a tracked config file without committing them

How do I keep my own version of a tracked file without Git nagging me?

Short answer

git update-index --skip-worktree <file> makes Git ignore your local modifications to a tracked file. The cleaner long-term answer is to commit an example file, ignore the real one, and have everyone copy it.

quick fix
git update-index --skip-worktree config/local.json

Git stops noticing your local edits to that tracked file

Does this match your situation?

  • A tracked config file needs different values on your machine.
  • You keep accidentally committing local database URLs or debug flags.
  • git stash keeps dragging along a file you never want to commit.

Step-by-step fix

  1. The proper fix — example file plus ignore rule

    Track a template and ignore the real file. This is the pattern nearly every project converges on, and it works for new contributors with no setup ritual.

    step 1
    git mv config/local.json config/local.example.json
    echo "config/local.json" >> .gitignore
    git add .gitignore config/local.example.json
    git commit -m "Track example config, ignore the local one"
    
    cp config/local.example.json config/local.json
    
  2. The quick fix — skip-worktree

    When the file must stay tracked, this tells Git to assume the index version is correct and ignore what's on disk. Your edits stop appearing in status and diff.

    step 2
    git update-index --skip-worktree config/local.json
    git status      # your changes no longer show
    
  3. Keep a list of what you've hidden

    This is the flag's real danger: months later a colleague's change to that file will silently fail to apply and it looks like a Git bug. Know how to audit it.

    step 3
    git ls-files -v | grep '^S'      # S = skip-worktree
    git ls-files -v | grep '^[a-z]'  # lowercase = assume-unchanged
    
    Show the PowerShell (Windows) version
    PowerShell (Windows)
    git ls-files -v | Select-String '^S'
    

    A pull that touches a skip-worktree file will fail or be silently ignored. Turn the flag off before pulling changes to it.

  4. Turn it back off

    Restore normal tracking when you need to see or accept changes to the file again.

    step 4
    git update-index --no-skip-worktree config/local.json
    git status
    
  5. Don't use --assume-unchanged for this

    It looks equivalent but it's a performance promise, not an ignore mechanism — Git may discard it at any time and your local edits reappear or get overwritten.

    step 5
    # avoid for this purpose:
    # git update-index --assume-unchanged <file>
    

Why this works

Git has exactly two states for a path: tracked or untracked. .gitignore only applies to untracked files, so a committed config file is always compared against the index no matter what ignore rules say. skip-worktree works around this by marking the index entry 'trust me, don't look at the filesystem', which suppresses the comparison. It's a local flag stored in your index only — nobody else sees it, which is what makes it convenient and also what makes a forgotten one so confusing later.

How to stop it happening again

  • Commit a .example config and ignore the real one from the start.
  • Read local overrides from environment variables instead of files.
  • Layer config: a tracked default plus an ignored local file that overrides it.

Commands used in this guide

git update-index

Manipulate the index directly - including telling Git to ignore changes to a tracked file.

git ls-files

List files in the index, with precise filters for state.

git rm

Delete a file from the repository - or just stop tracking it.

git config

Read and write Git settings for one repo, your user, or the whole machine.

Still stuck?

Search the full command reference and every other rescue guide — there are 56 of them, covering everything from detached HEAD to force-push disasters.

Browse all guides →

Frequently asked questions

How do I ignore changes to a file that's already tracked?

git update-index --skip-worktree <file> makes Git ignore your local modifications. The more maintainable fix is to untrack it with git rm --cached, add it to .gitignore, and commit a .example version instead.

What's the difference between --skip-worktree and --assume-unchanged?

skip-worktree means 'I have deliberate local changes here, leave them alone' and is designed to persist. assume-unchanged is only a performance hint that the file won't change, and Git is free to disregard it - which makes it unreliable for hiding real edits.

How do I find files I've marked skip-worktree?

git ls-files -v and look for lines starting with S. Lowercase status letters indicate assume-unchanged. Check this before concluding that Git is ignoring an incoming change for no reason.

Related rescue guides

← All Git Rescue guides