Git - Difference Between 'assume-unchanged' and 'skip-worktree'


I have local changes to a file that I don't want to commit to my repository. It is a configuration file for building the application on a server, but I want to build locally with different settings. Naturally, the file always shows up when I do 'git status' as something to be staged. I would like to hide this particular change and not commit it. I won't make any other changes to the file.

To clarify, using .gitignore is not what I want since that only prevents new files from being added. I want to ignore changes to a file already in the repository.

After some digging around, I see 2 options: assume-unchanged and skip-worktree. A previous question here talks about them but doesn't really explain their differences.

How are the two commands different? Why would someone use one or the other?


You want skip-worktree.

assume-unchanged is designed for cases where it is expensive to check whether a group of files have been modified; when you set the bit, git (of course) assumes the files corresponding to that portion of the index have not been modified in the working copy. So it avoids a mess of stat calls. This bit is lost whenever the file's entry in the index changes (so, when the file is changed upstream).

skip-worktree is more than that: even where git knows that the file has been modified (or needs to be modified by a reset --hard or the like), it will pretend it has not been, using the version from the index instead. This persists until the index is discarded.

There is a good summary of the ramifications of this difference and the typical use cases here: .

From that article:

  • --assume-unchanged assumes that a developer shouldn’t change a file. This flag is meant for improving performance for not-changing folders like SDKs.
  • --skip-worktree is useful when you instruct git not to touch a specific file ever because developers should change it. For example, if the main repository upstream hosts some production-ready configuration files and you don’t want to accidentally commit changes to those files, --skip-worktree is exactly what you want.

Unlink of file Failed. Should I try again?

How do I revert my changes to a git submodule?