git status显示".gitignore"中列出的文件未暂存,该怎么办?

16

让我们来看一下 .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 - 显示出来。


3
不要忽视被忽视。 - Anthony
2
嗯...你可能不想忽略.gitignore - user554546
如果我删除.gitignore文件,那么它会出现在“未提交的更改”中。 - WestCoastProjects
3
因为它没有被准备好提交,所以这样。 - Anonymoose
从“.gitignore”中移除“.gitignore”后,执行“git add .”。 你将不再遇到那个XML文件的问题。 - Makoto
.gitignore 的更改不需要添加或提交以使其生效。Git 将读取文件中的任何内容。 - Schwern
2个回答

33

.gitignore文件并不是您想象的那样。

特别地,一旦您将文件添加到git中,也就是在索引中,将该文件名添加到.gitignore中将不起作用。Git已经跟踪了这个文件,并且它将继续跟踪它。

实际上,.gitignore文件实际上不是要忽略的文件列表。相反,当git遇到"未跟踪"文件的情况并要向您报告时,.gitignore内容是应该被抑制的名称列表。

对于.gitignore文件本身,您可能只需要添加更改并提交它们,因为通常情况下,克隆您的存储库的任何人可能希望忽略相同的一组未跟踪文件,因此应该跟踪和版本控制.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评论所指出的,您可以使用git update-index --assume-unchanged使git甚至不会查看文件以进行更改,而不是使用git rm --cached将其从索引中删除(有关详细信息,请参见this answer)。就这样,只要你在其他/新的克隆上再次执行它(或让所有同事自己执行),那么也没问题了。

你可以使用git show <oldrev>:mllib/pom.xml > mllib/pom.xml从标准输出中转储文件,然后将标准输出重定向以重新创建该文件,以此来恢复。

1难以想象!

(更严肃地说,每个人都会犯这个错误。可能gitignore是错误的名称,如果有些笨重,像git-screen-away-untracked之类的东西可能更好。但是,在.gitignore中列出文件还有其他副作用:特别是,它允许Git在某些情况下覆盖这些文件。)


2
必须点赞这个 - 如果没有其他原因,也要因为使用了“不可思议”的词汇。遗憾的是,网页上无法复制正确的变调。感谢您深入探讨此事 - .gitignore 实际上比预期更加复杂。我将逐渐学习一些方法来处理仅需要针对 pom.xml 处理本地更改的情况。 - WestCoastProjects
@javadba 这个答案 应该提供了忽略已跟踪文件的本地更改的解决方案。 - Schwern
@Schwern:我可能应该提到--assume-unchanged的技巧。个人而言,我不太喜欢它,因为每个克隆仓库的人都必须这样做,但我主要是尽量避免首先陷入这种情况。(另外,我添加了你的视频链接!:D) - torek
@torek 这不是最好的方法,但这是我见过的唯一一个在存储库中拥有文件但避免意外更改它(例如使用 git add .)的方法。当然,您可以想办法首先避免出现此问题。 - Schwern
如果我使用“git update-index --skip-worktree”,然后运行:“git commit -a”,那么“所有”(例如“-a”)的提交是否仍将忽略skip-worktree项目?还是会提交它们? - Auxiliary Joel
显示剩余5条评论

1

在您将文件添加到 .gitignore 并将该文件推送到 git 后,然后发出以下命令:

git restore . 

那么,git status 将不再显示您已添加到 .gitignore 的文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接