Git 如何避免完全跟踪某些文件?

Git 如何避免完全跟踪某些文件?,git,Git,我是Git的新手/中级,但我在理解阶段索引方面遇到了一些问题。我是一名iOS开发人员,每次我处理一个XCode项目,然后在我的项目文件夹中运行git status时,我经常会看到像info.plist或.DS\u Store这样的文件不会被提交 我不关心这样的文件,也不想提交它们。我怎样才能告诉git完全忽略这些文件,而不提示我将它们转移到后台 我尝试在我的主目录中设置一个包含以下内容的.gitignore\u global: # Compiled source # ##############

我是Git的新手/中级,但我在理解阶段索引方面遇到了一些问题。我是一名iOS开发人员,每次我处理一个XCode项目,然后在我的项目文件夹中运行git status时,我经常会看到像
info.plist
.DS\u Store
这样的文件不会被提交

我不关心这样的文件,也不想提交它们。我怎样才能告诉git完全忽略这些文件,而不提示我将它们转移到后台

我尝试在我的主目录中设置一个包含以下内容的
.gitignore\u global

# Compiled source #
###################
*.com
*.class
*.dll
*.exe
*.o
*.so

# Packages #
############
# it's better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip

# Logs and databases #
######################
*.log
*.sql
*.sqlite

# OS generated files #
######################
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# XCode Related files #
######################
*.plist
但这似乎不起作用。我在网上看到过关于使用git rm的帖子——缓存以取消跟踪文件,但随后它显示为一个要“删除”的文件。我不想做出这样的改变,让任何人感到恐慌


告诉git永久忽略文件的正确解决方案是什么?

全局
。gitignore
文件应配置
核心。excludesfile
全局选项,否则git不会应用它:

$ git config --global core.excludesfile ~/.gitignore_global
例如,您可能需要以下内容:

$ git config --global core.excludesfile ~/.gitignore_global
但这并不能解决现有的问题

问题 提交是一个Git对象,它存储文件(作为快照)和一些元数据。每个提交都有一个唯一的散列ID:世界上每一个拥有该提交的Git,都通过该散列ID拥有它;任何其他提交都不能具有相同的哈希ID。请注意,提交将永远冻结。宇宙中任何力量都无法改变现有的承诺。1

现在,假设您已经将一些想要忽略的文件放入某个现有的提交中。别管它是怎么进来的,只是想想它在里面。如果您
git checkout
提交该文件,git将把该文件复制到您的索引和工作树中

您的索引在很大程度上是不可见的,但它保存了您刚刚签出的提交中每个文件的副本。Git从通过提交存储的deep-freeze版本中获取文件,将其复制或从技术上说,将其blob散列复制到您的索引中,然后将文件复制到您的工作树中,以便您可以查看和处理它。索引也是构建下一次提交的位置

当您运行
git add
时,您告诉您的git:立即获取我的工作树中的文件版本,并将其复制到索引中。这会覆盖以前的副本,即使
git status
没有对新的、不同的副本说任何话。如果现在运行
git commit
,则新提交的文件已更新。它还包含您未覆盖的所有未更新文件。这就是为什么每次提交都是所有文件的完整快照:git commit命令实际上从索引进行提交。索引始终保存所有文件


1您可以停止使用提交,让Git忘记它曾经存在过。当然,它仍然存在,除非并且直到每个拥有提交的Git回购都放弃它。在那之后,hash ID(提交的真实名称)只会引发一个:说什么?我不知道世界上每一个Git都会通过hash-ID响应进行提交。要删除提交,还必须删除其所有子代,因为提交的哈希ID部分地是从每个祖先提交的哈希ID构建的。有关更多信息,请参阅Wikipedia上的文章

此外,两个不同的提交可以共享相同的哈希ID,前提是这两个Git永远不会相遇。(我喜欢将这些视为doppelgänger提交。)如果这两个Git真的相遇,他们将拒绝共享doppelgänger提交,任何其他将doppelgänger提交作为其历史一部分的提交也不能进入另一个Git


所有这些与
.gitignore
和跟踪文件有什么关系? 跟踪文件是索引中的文件

就这样。就这些。当且仅当文件现在在索引中时,才会跟踪该文件。工作树中但不在索引中的文件未被跟踪

所以,假设
.DS\u Store
现在在您的工作树中(因为Finder已经编写或创建了它)。
.DS\u Store
现在是否在您的索引中?如果是这样的话,它会被追踪。如果没有,它是未跟踪的

.gitignore
中列出一个文件会告诉Git如果该文件未被跟踪,Git应该:

  • 不要对此抱怨,并且
  • 当您使用大量文件(
    *
    或其他任何文件)的git add时,不会自动添加文件
事实上,如果
.DS_Store
文件未被跟踪,并且您将其列在
.gitignore
中,并且您显式运行
git add.DS_Store
,即使这样也不会添加它:它会告诉您该文件已被忽略,如果确实需要添加它,您应该使用
--force

但是。。。如果
.DS\u Store
已在索引中,该怎么办?在这种情况下,在
.gitignore
中列出它没有任何效果。它已经被跟踪了。太晚了!您可以
git-rm
it,使用或不使用
--cached
,立即将其从索引中删除。那它就不被追踪了。它不会出现在下一次提交中

这不会将其从任何已有的提交中删除。什么也做不到。通过散列ID找到的这些提交将永远包含
.DS\u Store

你能做些什么 您可以进行新的和改进的(但不同,不同的哈希ID)提交,这些提交与旧提交类似,但没有文件。因为提交对它们的祖先散列ID进行编码,所以您必须对存储库中的几乎每次提交都这样做。然后,您可以让自己和世界上使用此Git存储库或其克隆的所有人从旧的提交切换到新的和改进的提交。这是相当痛苦的,尽管对于这个Git存储库或其克隆的每个用户来说都是一次性的痛苦。
git过滤器-b