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
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
| Flag | What it does |
|---|---|
| --assume-unchanged | Set the assume-unchanged bit (performance hint) |
| --no-assume-unchanged | Clear the assume-unchanged bit |
| --skip-worktree | Mark the file to be preserved locally |
| --no-skip-worktree | Clear the skip-worktree bit |
| --refresh | Re-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.