Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git ignore vs. exclude vs. assume-unchanged

Tags:

git

gitignore

I've read the docs on this several times over and I still don't completely get the differences between these different commands. Maybe it's just me, but the documentation could be more lucid:

http://git-scm.com/docs/gitignore

https://help.github.com/articles/ignoring-files

Moreover, a lot of the commentary on this subject seems to use the words "indexed", "committed", "tracked" somewhat loosely, which makes the differences between these three less clear.

My current (admittedly limited) understanding:

  • Files matched in .gitignore will not be tracked in the future. (Though they may have been tracked previously.) This means that they won't ever show up in a future git status list as changed. However, future changes will still be synced with remote repos. In other words, the files are still "indexed", but they are not "tracked". Because a .gitignore file is in the project directory, the file itself can be versioned.

  • Files matched in .git/info/exclude will also not be "tracked". In addition, these files will not ever be remotely synced, and thus will never be seen in any form by any other users. These files should be files that are specific to a single user's editor or workflow. Because it is in the .git directory, the exclude file can't itself be versioned.

  • Files that have had assume-unchanged run on them also don't show up in git status or git diff. This seems similar to exclude, in that these files are neither "indexed" nor "tracked". However, the last version of the file to be committed before assume-unchanged will remain visible to all users in the repo.

My questions:

  1. Is the above interpretation correct? Please correct me.

  2. If a file has already been in a commit, what is the functional different between matching it in .exclude and running assume-unchanged on it? Why would one prefer one approach to another?

  3. My basic use case is that I want to avoid sorting through diffs on compiled files, but I still want those compiled files synced along with the source files. Will a gitignore'd file still be pushed? If not, how to manage final deployment of the compiled files?

Thanks in advance for any help.

like image 329
Ben Avatar asked Apr 16 '14 01:04

Ben


1 Answers

I'm going to accept this emailed answer from Junio Hamano (the maintainer of Git) because I think it explains some things more lucidly than the official docs, and it can be taken as "official" advice:

The .gitignore and .git/info/exclude are the two UIs to invoke the same mechanism. In-tree .gitignore are to be shared among project members (i.e. everybody working on the project should consider the paths that match the ignore pattern in there as cruft). On the other hand, .git/info/exclude is meant for personal ignore patterns (i.e. you, while working on the project, consider them as cruft).

Assume-unchanged should not be abused for an ignore mechanism. It is "I know my filesystem operations are slow. I'll promise Git that I won't change these paths by making them with that bit---that way, Git does not have to check if I changed things in there every time I ask for 'git status' output". It does not mean anything other than that. Especially, it is not a promise by Git that Git will always consider these paths are unmodified---if Git can determine a path that is marked as assume-unchanged has changed without incurring extra lstat(2) cost, it reserves the right to report that the path has been modified (as a result, "git commit -a" is free to commit that change).

like image 174
Ben Avatar answered Oct 01 '22 07:10

Ben