Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

git

git-index

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?

like image 573
ckb Avatar asked Nov 29 '12 17:11

ckb


People also ask

What is git assume unchanged?

When the "assume unchanged" bit is on, the user promises not to change the file and allows Git to assume that the working tree file matches what is recorded in the index. If you want to change the working tree file, you need to unset the bit to tell Git.

What is a git Worktree?

A Git worktree is a linked copy of your Git repository, allowing you to have multiple branches checked out at a time. A worktree has a separate path from your main working copy, but it can be in a different state and on a different branch.

What is the git index?

The Git index is a critical data structure in Git. It serves as the “staging area” between the files you have on your filesystem and your commit history. When you run git add , the files from your working directory are hashed and stored as objects in the index, leading them to be “staged changes”.


1 Answers

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: http://fallengamer.livejournal.com/93321.html .

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.
like image 143
Borealid Avatar answered Sep 21 '22 12:09

Borealid