git ignore vs. exclude vs. assume-unchanged

时间:2014-04-16 01:24:25

标签: git gitignore

我已经多次阅读过这方面的文档了,我仍然没有完全理解这些不同命令之间的差异。也许它只是我,但文档可能更清晰:

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

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

此外,很多关于这个主题的评论似乎都使用了"索引","承诺","跟踪"有点松散,这使得这三者之间的差异不太明显。

我当前(无可否认有限)的理解:

  • 将来不会跟踪.gitignore中匹配的文件。 (虽然它们之前可能已被跟踪过。)这意味着它们 永远不会出现在未来的git status列表中。 但是,未来的更改仍会与远程回购同步。换句话说,文件仍然被编入索引",但它们没有被跟踪"。 因为.gitignore文件位于项目目录中,所以该文件 本身可以版本化。

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

  • 运行assume-unchanged的文件也不会显示在git statusgit diff中。这似乎与exclude类似,因为这些文件既没有被索引也没有#34;也没有"跟踪"。但是,在assume-unchanged之前提交的文件的最后一个版本对于仓库中的所有用户仍然可见。

我的问题:

  1. 上述解释是否正确?请纠正我。

  2. 如果文件已经在提交中,那么功能是什么 在.exclude和正在运行之间进行匹配 assume-unchanged就可以了?为什么人们更喜欢一种方法 另一

  3. 我的基本用例是我想避免在差异上进行排序 已编译的文件,但我仍然希望这些编译的文件同步 与源文件。还会推送gitignore个文件吗?如果没有,如何管理已编译文件的最终部署?

  4. 提前感谢您的帮助。

4 个答案:

答案 0 :(得分:71)

我将接受this emailed answer from Junio Hamano(Git的维护者),因为我认为它比官方文档更清晰地解释了一些事情,并且它可以被视为"官方"建议:

  

.gitignore和.git / info / exclude是要调用的两个UI   同样的机制。树内.gitignore将在项目之间共享   成员(即每个从事该项目的人都应该考虑这个问题   与那里的忽略模式相匹配的路径。在另一   手,.git / info / exclude用于个人忽略模式(即   你在开展这个项目的过程中,认为它们是残酷的。)

     

假设 - 忽略机制不应滥用。它是   "我知道我的文件系统操作很慢。我会答应Git我   通过用那个位做出改变来改变这些路径 - 就这样,Git   每次问我都不必检查我是否改变了东西   为了' git status'输出&#34 ;.除此之外,它并不意味着什么。   特别是Git一直在考虑的是不是 Git的承诺   这些路径是未修改的 - 如果Git可以确定路径   标记为假设未更改已更改而不会产生额外费用   lstat(2)成本,它保留报告该路径的权利   已被修改(因此," git commit -a"可以自由提交更改)。

答案 1 :(得分:8)

添加到Junio Hamano的answer,Git 2。3。0(2015年2月),现在gitignore documentation删除

  

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

请参阅commit 936d2c9中的Michael J Gruber (mjg)

  

gitignore.txt:不建议assume-unchanged

     

git-update-index --assume-unchanged从未打算忽略对跟踪文件的更改(仅提供一些统计信息)。
  因此,不要将其作为实现这一目标的手段。

答案 2 :(得分:4)

希望没有太多的信息来源使用跟踪,索引和承诺松散,因为它们都是不同的和有意义的。

  • 索引表示该文件位于git索引中。在过去的某个时刻,有人在文件上使用git add或等效命令。该文件已被跟踪,也可能已提交。
  • 跟踪意味着git正在观看文件的更改。将跟踪任何已提交的文件或索引中的任何文件。
  • 已提交意味着该文件位于git的历史记录中。此文件至少有一个检查点;您可以恢复到该文件的任何已提交版本。

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

  

提交索引文件时,它不再位于索引中。下次修改(或删除)时,它将返回索引中。 索引是所有跟踪文件的总和,与提交的内容不同

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

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

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

Re:第3点:你不应该把编译好的文件添加到git中。将文件编译到源所在的其他目录,并忽略整个目录。将编译好的文件捆绑到一个库中并将其添加到工件库中,但不要将它们放在git中。

答案 3 :(得分:1)

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

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

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