git忽略vs.排除vs.假设不变


74

我已经多次阅读了有关此文档的文档,但仍然没有完全理解这些不同命令之间的区别。也许只有我一个人,但是文档可能更加清晰:

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 status或中git diff。这似乎与相似exclude,因为这些文件既没有“建立索引”也没有“跟踪”。但是,之前要提交的文件的最新版本将对存储库assume-unchanged中的所有用户可见。

我的问题:

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

  2. 如果文件已经在提交,什么是它匹配之间的功能不同的.exclude运行 assume-unchanged就可以了?为什么一个人会偏爱一种方法?

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

在此先感谢您的帮助。

Answers:


102

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

.gitignore和.git / info / exclude是调用同一机制的两个UI。树内.gitignore将在项目成员之间共享(即,每个在项目上工作的人都应将与其中的忽略模式匹配的路径视为无效的)。另一方面,.git / info / exclude用于个人忽略模式(即,您在从事项目工作时,将其视为杂项)。

假定不变的机制不应被滥用。这是“我知道我的文件系统操作很慢。我向Git保证,我不会通过使用该位来更改这些路径-那样,Git不必每次检查是否更改了其中的内容我要求输出“ git status”。除此之外,它没有其他含义。特别是,Git不能保证Git始终会认为这些路径是未修改的---如果Git可以确定标记为假定不变的路径已更改而又不产生额外的lstat(2)成本,则它保留以下权利:报告该路径 已被修改(因此,“ git commit -a”可以自由提交该更改)。


5
“通过用这种方式使它们变得那样”?这意味着什么?
蓝云

3
@BlueClouds,“以这种方式”后面有一个逗号,因为这是一个新想法的开始。我怀疑“用该位创建它们”是要说“标记”,并将“假定不变”创建的标志称为“位”,我想这种标记只需要存储一点,因为它是二进制状态。我承认这部分是猜测,但我不难理解答案,因此也许会对您有所帮助。
通配符

@Wildcard我必须同意BlueClouds:我也很难理解“位---那”的含义。您可能对git的内部知识了解得更多,以便能够填补这些空白,但是对于包括我在内的许多其他人来说,它仍然是一堆杂乱无章的魔术。
Suncat2000

2
人们,作品中有一个错字marking,它变成了“制作”。它的全部意思是每个文件都有一些git保留的标志,并且可以使用该管道命令设置和重置该标志。
Leonid Usov '18

此外,请注意,此标志保留在索引中,并且在重置索引的操作后其值将丢失。请参阅(this)[ stackoverflow.com/a/13631525/5171225]答案以获得更清晰的信息
Leonid Usov '18

12

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

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

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

gitignore.txt:不建议 assume-unchanged

git-update-index --assume-unchanged从来都不打算忽略对跟踪文件的更改(只是为了节省一些统计信息)。
因此,请勿将其作为实现此目标的方法。


5

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

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

现在就我所知。我不确定这个定义,但这是我的理解;很高兴对此进行纠正:

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

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

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

假定未更改仅影响跟踪的文件,因此与.gitignore完全分开。它可以暂时假装该文件未跟踪并被忽略(但它不一定必须也不能与正常行为有所不同)。就像其他答案提到的那样,这并不是用来忽略对文件的更改,只是为了潜在地避免在慢速文件系统上进行文件系统操作。

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


1

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

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

  2. 假定不变的跟踪文件。如果文件具有配置信息但可以由团队修改,这将非常有用。如果一个文件被设置为假定不变但被其他人更改并被推送到远程存储库,则git会在尝试从远程拉出时提示您。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.