忽视git忽略与假设 – 不变

我已经阅读过几次这些文档,但是我仍然不完全明白这些不同命令之间的差异。 也许这只是我,但文件可以更清晰:

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

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

而且,这个问题上的很多评论似乎都是用“索引”,“承诺”,“跟踪”这个词来略微松散一些,这就使得这三者之间的分歧不甚清楚。

我目前(固然有限)的理解:

  • .gitignore匹配的文件将不会被跟踪。 (虽然他们以前可能已经被跟踪了。)这意味着他们将不会在未来的git status列表中显示出来。 但是,未来的变化仍然会与远程回购同步 。 换句话说,这些文件仍然被“索引”,但是它们不被“追踪”。 由于.gitignore文件位于项目目录中,因此文件本身可以进行版本控制。

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

  • 已经assume-unchanged运行的文件也不会在git statusgit diff显示出来。 这与exclude似乎相似,因为这些文件既不是“索引”也不是“跟踪”的。 但是,在assume-unchanged之前要提交的最后一个版本的文件对于回购中的所有用户都将保持可见。

我的问题:

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

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

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

在此先感谢您的帮助。

我将接受来自Gio的维护者Junio Hamano的电子邮件答案,因为我认为它比官方文档更清晰地解释了一些事情,可以作为“官方”的build议:

.gitignore和.git / info / exclude是调用相同机制的两个UI。 In-tree .gitignore将在项目成员之间共享(即,在项目中工作的每个人都应该考虑与那里的忽略模式匹配的path)。 另一方面,.git / info / exclude是为个人忽略模式而devise的(也就是说,当你在项目上工作的时候,把它们看作是一个垃圾)。

假设 – 不变不应该被忽略机制。 这是“我知道我的文件系统操作很慢,我会保证Git不会改变这些path – 这样,Git不必每次都检查是否在那里改变了东西我要求'git状态'输出“。 除此之外,这并不意味着什么。 特别是Git 没有承诺Git会一直认为这些path是未经修改的 – 如果Git能够确定一个被标记为假设的path – 在没有额外的成本的情况下已经改变了,它保留权利报告该path已被修改(因此,“git commit -a”可以自由地提交该更改)。

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

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

参见Michael J Gruber( mjg )的 commit 936d2c9 :

gitignore.txt :不build议assume-unchanged

git-update-index --assume-unchanged从未打算忽略对跟踪文件的更改( 只是为了 git-update-index --assume-unchanged 一些统计信息 )。
所以不要把它作为实现这个目标的手段。

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

  • 索引意味着文件在git索引中。 在过去的某个时候,有人在文件上使用git add或者一个等价的命令。 该文件被跟踪,也可能被提交。
  • 跟踪意味着git正在监视文件的更改。 跟踪任何提交的文件或索引中的任何文件。
  • 承诺意味着该文件在git的历史。 这个文件至less有一个检查点。 你可以恢复到任何提交的文件版本。

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

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

该索引也称为caching或暂存区域。

谈到你的主要问题。 .git / info / exclude与.gitignore相同,只是优先级较低,不在存储库中(所以不提交和共享)。 既不影响已经跟踪的文件。 两者都会影响当前未被跟踪的文件。 在git addgit commit后更新.gitignore太迟了; git已经跟踪文件,.gitignore不会影响这个。

假设 – 不变只影响跟踪的文件,因此完全独立于.gitignore。 它可以暂时假装文件未被跟踪并被忽略(但是它不需要,也可以不做任何与正常行为不同的东西)。 正如其他答案所提到的,这不会用于忽略对文件的更改,只是为了避免慢文件系统上的文件系统操作。

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

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

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

  2. 假设 – 不变是被跟踪的文件。 如果文件具有configuration信息,但是可以由团队修改,则非常有用。 如果一个文件被设置为假定不变,但被其他人改变并推送到远程存储库,那么git会在试图从远程获取时提醒。