Skip to content
Latchkey

git update-index --assume-unchanged and --skip-worktree

git update-index --assume-unchanged <file> tells git to stop checking that tracked file for changes (a performance hint), while --skip-worktree marks it as locally modified and not to be touched.

These two flags both hide changes to tracked files, but they mean different things. assume-unchanged is a performance hint git may ignore; skip-worktree expresses real intent to keep a local version. CI scripts misuse them often, so the distinction matters.

What it does

git update-index manipulates the staging index directly. --assume-unchanged sets a bit telling git not to bother checking that file for modifications (a speed hint on slow filesystems); git is free to ignore it, and operations like checkout or pull can overwrite the file. --skip-worktree is stronger: git tries to preserve the local file across many operations, intended for config you must keep locally edited.

Common usage

Terminal
git update-index --assume-unchanged config/local.json
git update-index --no-assume-unchanged config/local.json   # undo
# keep a locally edited file from being overwritten
git update-index --skip-worktree .env.local
# list files with the skip-worktree bit (S in column 2)
git ls-files -v | grep '^S'

Options

FlagWhat it does
--assume-unchangedSet the assume-unchanged bit (performance hint)
--no-assume-unchangedClear the assume-unchanged bit
--skip-worktreeMark the file to be preserved locally
--no-skip-worktreeClear the skip-worktree bit
--refreshRe-check stat info for index entries
--chmod=+x <file>Set the executable bit in the index

In CI

Do not use assume-unchanged to hide secrets or config in CI: a fresh clone does not carry these bits, and any pull/checkout can overwrite the file anyway. If a checkout or merge in CI reports the file changed despite the bit, that is assume-unchanged working as designed (it is only a hint). For genuinely local-only files, .gitignore or skip-worktree is more reliable, but neither survives a clean clone.

Common errors in CI

"error: Your local changes to the following files would be overwritten by checkout" can appear even on assume-unchanged files, because the bit is advisory. "fatal: Unable to mark file <x>" means the path is not tracked; the flags only apply to files already in the index. The bits are per-clone and silently absent in CI runners.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →