对于.gitignore中列出的文件,git status显示“未提交提交的更改”?

时间:2015-01-23 00:15:55

标签: git gitignore

让我们看一下.gitignore文件 - 我添加了mllib / pom.xml和pom.xml甚至.gitignore(这不应该是必要的 - 所以有些不对......):

$head .gitignore
.gitignore
mllib/pom.xml
pom.xml

那么让我们看看git想要添加的文件:

$ git status
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   .gitignore
    modified:   mllib/pom.xml
    modified:   

更新有两条评论没有“忽略.gitignore”。但是在再次移除.gitignore之后我们得到了这个:

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   .gitignore
    modified:   mllib/pom.xml

所以(a).gitignore正在显示,(b)真正重要的不添加到提交的特定文件 - mllib / pom.xml - 显示。

1 个答案:

答案 0 :(得分:24)

.gitignore文件并不代表您认为的含义。 1

特别是,一旦你为git创建了一个“已知”文件,因为它在索引中,将该文件的名称添加到.gitignore没有任何效果。 Git已经跟踪了该文件,它将继续跟踪它。

实质上,.gitignore文件实际上不是要忽略的文件列表。相反,当git遇到“未跟踪”文件的情况并且即将向您报告时,.gitignore内容是它应该禁止的名称列表。

对于.gitignore文件本身,您可能只想git add更改并提交它们,因为作为一般规则,任何克隆您的存储库的人可能都想忽略同一组未跟踪文件,所以应跟踪.gitignore并对其进行版本控制。

但是,对于XML文件,它可能是“生成的内容”,您不希望版本控制,但您仍希望将其保留在工作树中。这有点问题,因为git已经在跟踪它并且将坚持继续对文件进行版本控制。

此时你可以做的是将它从git的索引中删除,而不是从工作树中删除:

git rm --cached mllib/pom.xml

就目前而言这很好(git从索引中删除文件,下一次提交将缺少该文件),但如果你回到的提交,它会产生问题该文件,因为git将看到它需要创建文件 - 您正在从文件不存在的提交(最近的一个)转移到它确实存在的提交(旧的) - 并且可能抱怨该文件的内容将被破坏。或者,即使这部分有效,如果你再回到最近的版本,远离旧版本,git会比较旧版本和新版本并看到该文件已被删除...并将删除 mllib/pom.xml

重新编辑,2016年10月20日:使用git update-index --skip-worktree,而不是git update-index --assume-unchanged。这在索引中设置了更强大的位。见Git - Difference Between 'assume-unchanged' and 'skip-worktree'修改:作为Schwern noted in a comment below,您可以使用git update-index --assume-unchanged使git在文件中找不到外观进行更改,而不是使用git rm --cached将其从索引中取出(有关详细信息,请参阅this answer)。这也很好,你可能不得不再次(或让所有同事自己做)在任何其他/新克隆上。

(您可以使用git show <oldrev>:mllib/pom.xml > mllib/pom.xml将文件转储到标准输出,然后重定向标准输出以重新创建文件,从后者恢复。)


1 Inconceivable!

(更严重的是,每个人都犯了这个错误。可能gitignore错误的名称,git-screen-away-untracked之类的内容可能会更好,如果是klunkier。但是,在.gitignore列出文件还有其他副作用:具体来说,在某些情况下permits Git to clobber such files。)