git ignore vs. exclude vs. 假设不变

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23097368/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 18:00:36  来源:igfitidea点击:

git ignore vs. exclude vs. assume-unchanged

gitgitignore

提问by Ben

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

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

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

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 .gitignorewill 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 statuslist 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 .gitignorefile is in the project directory, the file itself can be versioned.

  • Files matched in .git/info/excludewill 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 .gitdirectory, the excludefile can't itself be versioned.

  • Files that have had assume-unchangedrun on them also don't show up in git statusor 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-unchangedwill remain visible to all users in the repo.

  • .gitignore将来不会跟踪匹配的文件。(尽管它们之前可能已被跟踪。)这意味着它们将永远不会git status以更改的形式出现在未来的列表中。 但是,未来的更改仍将与远程 repos 同步。换句话说,文件仍然被“索引”,但不会被“跟踪”。由于.gitignore文件位于项目目录中,因此可以对文件本身进行版本控制。

  • 匹配的文件.git/info/exclude也不会被“跟踪”。此外,这些文件永远不会被远程同步,因此任何其他用户永远不会以任何形式看到这些文件。这些文件应该是特定于单个用户的编辑器或工作流的文件。因为它在.git目录中,exclude所以不能对文件本身进行版本控制。

  • 已在其上assume-unchanged运行的文件也不会出现在git status或 中git diff。这似乎类似于exclude,因为这些文件既不是“索引”也不是“跟踪”。但是,之前要提交的文件的最后一个版本将对存储库assume-unchanged中的所有用户保持可见。

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 .excludeand running assume-unchangedon 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?

  1. 以上解释正确吗?请纠正我。

  2. 如果一个文件已经在提交中,那么匹配它.exclude和运行 assume-unchanged它之间的功能有什么不同?为什么人们更喜欢一种方法而不是另一种方法?

  3. 我的基本用例是我想避免对编译文件的差异进行排序,但我仍然希望那些编译文件与源文件同步。将一个gitignore“d文件仍然推?如果没有,如何管理编译文件的最终部署?

Thanks in advance for any help.

在此先感谢您的帮助。

回答by Ben

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:

我将接受Junio Hamano(Git 维护者)的电子邮件答复,因为我认为它比官方文档更清楚地解释了一些事情,并且可以将其视为“官方”建议:

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 nota 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 beenmodified (as a result, "git commit -a" is free to commit that change).

.gitignore 和 .git/info/exclude 是调用相同机制的两个 UI。In-tree .gitignore 将在项目成员之间共享(即每个在项目中工作的人都应该将与那里的忽略模式匹配的路径视为 cruft)。另一方面, .git/info/exclude 用于个人忽略模式(即您在进行项目时,将它们视为垃圾)。

Assume-unchanged 不应被滥用于忽略机制。它是“我知道我的文件系统操作很慢。我会向 Git 保证我不会通过使用那个位来改变这些路径——这样,Git 就不必每次都检查我是否在那里改变了东西我要求'git status'输出”。除此以外没有任何其他意义。特别是,Git并没有承诺 Git 将始终认为这些路径是未修改的——如果 Git 可以确定标记为假设未更改的路径已更改而不会产生额外的 lstat(2) 成本,则它保留以下权利:报告路径 已被修改(因此,“git commit -a”可以自由提交该更改)。

回答by VonC

Adding to Junio Hamano's answer, Git 2.3.0 (February 2015) now removesfrom the gitignoredocumentation

添加到 Junio Hamano 的回答中,Git 2.3.0(2015 年 2 月)现在从文档中删除gitignore

To ignore uncommitted changes in a file that is already tracked, use 'git update-index --assume-unchanged'.

要忽略已跟踪文件中未提交的更改,请使用“ git update-index --assume-unchanged”。

See commit 936d2c9from Michael J Gruber (mjg):

提交936d2c9迈克尔·格鲁伯Ĵ( )mjg

gitignore.txt: do not suggest assume-unchanged

git-update-index --assume-unchangedwas never meant to ignore changes to tracked files (only to spare some stats).
So do not suggest it as a means to achieve that.

gitignore.txt: 不建议 assume-unchanged

git-update-index --assume-unchanged从来没有打算忽略对跟踪文件的更改(只是为了节省一些统计数据)。
因此,不要建议将其作为实现这一目标的手段。

回答by Paul Hicks

Hopefully, not too many sources of information are using tracked, indexed and committed loosely, since they are all different and meaningful.

希望不会有太多的信息源在松散地使用跟踪、索引和提交,因为它们都是不同且有意义的。

  • Indexed means that the file is in the git index. At some point in the past, someone has use git addor an equivalent command on the file. The file is tracked, and might also be committed.
  • Tracked means that git is watching the file for changes. Any committed file, or any file in the index is tracked.
  • Committed means that the file is in git's history. There is at least one checkpoint for this file; you can revert to any committed version of the file.
  • 已索引意味着文件在 git 索引中。在过去的某个时候,有人git add在文件上使用过或等效的命令。该文件被跟踪,也可能被提交。
  • 跟踪意味着 git 正在监视文件的更改。任何提交的文件或索引中的任何文件都会被跟踪。
  • 已提交意味着该文件在 git 的历史记录中。该文件至少有一个检查点;您可以恢复到文件的任何提交版本。

Now to the limit of my own knowledge. I'm not sure about this definition, but this is my understanding; happy to be corrected about this:

现在到了我自己知识的极限。我不确定这个定义,但这是我的理解;很高兴得到纠正:

when an indexed file is committed, it is no longer in the index. The next time it is modified (or deleted), it is back in the index. The index is the sum of all tracked files that differ from what's committed.

当提交索引文件时,它不再在索引中。下次修改(或删除)时,它又回到索引中。 索引是与提交的不同的所有跟踪文件的总和

The index is also called the cache, or the staging area.

索引也称为缓存或暂存区。

On to your main question. .git/info/exclude is the same as .gitignore, just a lower precedence and not in the repository (so, not committed and shared). Neither affects already tracked files. Both affect files that are not currently tracked. Updating .gitignore after git addor git commitis too late; git already tracks the file, and .gitignore won't affect that.

关于你的主要问题。.git/info/exclude 与 .gitignore 相同,只是优先级较低,并且不在存储库中(因此,未提交和共享)。两者都不会影响已跟踪的文件。两者都会影响当前未跟踪的文件。更新 .gitignore 之后git addgit commit为时已晚;git 已经跟踪文件,而 .gitignore 不会影响它。

Assume-unchanged affects only tracked files, and thus is completely separate to .gitignore. It can temporarily pretend that the file is untracked and ignored (but it doesn't have to and can also do nothing different from normal behaviour). As other answers mention, this is not used for ignoring changes to files, just for potentially avoiding file system operations on slow file systems.

Assume-unchanged 只影响跟踪的文件,因此与 .gitignore 完全分开。它可以暂时假装文件未被跟踪和忽略(但它不必也可以做与正常行为不同的任何事情)。正如其他答案所提到的,这不是用于忽略对文件的更改,只是为了可能避免在慢速文件系统上进行文件系统操作。

Re: point 3: you should not add compiled files to git. Compile your files to a different directory that your source is in, and ignore that entire directory. Bundle your compiled files into a library and add it to an artifact repository, but don't put them in git.

回复:第 3 点:您不应该将编译后的文件添加到 git。将文件编译到源所在的不同目录,并忽略整个目录。将编译后的文件捆绑到一个库中并将其添加到工件存储库中,但不要将它们放入 git 中。

回答by guest

I think the difference of .gitignore and assume-unchanged are

我认为 .gitignore 和假设不变的区别是

  1. .gitignore can be shared with other people in the team but assume-unchanged has to be configured for each member individually.

  2. assume-unchanged are tracked files. It is very useful if a file has configuration information but can be modified by the team. If a file is set as assume-unchanged but changed by other people and pushed to the remote repository, git will remind when try to pull from the remote.

  1. .gitignore 可以与团队中的其他人共享,但必须为每个成员单独配置假设不变。

  2. 假设未更改是跟踪文件。如果文件具有配置信息但可以由团队修改,这将非常有用。如果文件被设置为假设未更改但被其他人更改并推送到远程存储库,则尝试从远程拉取时 git 会提醒。