【问题标题】:git status is showing "Changes not staged for commit" for files listed in .gitignore?git status 显示 .gitignore 中列出的文件的“更改未暂存以进行提交”?
【发布时间】:2015-01-23 00:15:55
【问题描述】:

让我们看看 .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 - 出现了。

【问题讨论】:

  • 不要忽略忽略
  • 呃……你可能不想忽略.gitignore
  • 如果我删除 .gitignore 然后它会显示在“未暂存的更改”中
  • 那是因为它不是为提交准备的...
  • .gitignore 中删除.gitignore 后,执行git add .。你不会再对那个 XML 文件有任何问题了。

标签: git gitignore


【解决方案1】:

.gitignore 文件并不像您认为的那样。1

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

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

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

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

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

git rm --cached mllib/pom.xml

就目前而言这很好(git 从索引中删除文件,并且下一次提交将缺少该文件),但是如果您返回到 确实 有的提交,它会产生问题文件,因为 git 会看到它需要创建文件——你正在从文件不存在的提交(最近的提交)移动到文件确实存在的提交(旧的提交)——并且可能抱怨该文件的内容将被破坏。或者,即使这部分有效,如果您随后移回最近的版本,远离旧版本,git 将比较旧版本和新版本并查看文件已被删除......并将 remove 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 &lt;oldrev&gt;:mllib/pom.xml &gt; mllib/pom.xml将文件转储到标准输出,并重定向标准输出以重新创建文件来从后者中恢复。)


1Inconceivable!

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

【讨论】:

  • 必须对此表示支持 - 如果没有其他原因使用“不可思议”。太糟糕了,正确的变形不能从网页上重现。感谢您深入研究 - .gitignore 实际上比预期的要复杂得多。我将逐步学习一些方法来处理 pom.xml 所需的 local-changes-only 处理
  • @javadba This answer 应该提供一个解决方案来忽略对跟踪文件的本地更改。
  • @Schwern:我可能应该提到--assume-unchanged 技巧。我个人不喜欢它,因为每个克隆存储库的人也必须这样做,但大多数情况下,我只是尽量避免一开始就陷入这种情况。 (另外,添加了您的视频链接!:D)
  • @torek 这不是最好的,但这是我见过的唯一一个在存储库中有文件但避免意外更改它的东西(比如git add .)。当然,您可以设法从一开始就没有问题。
  • 如果我使用 'git update-index --skip-worktree' 然后运行: 'git commit -a' 将“所有”的提交(例如“-a”)仍然忽略跳过工作树项目?还是会提交他们?
猜你喜欢
  • 2020-12-15
  • 2015-11-29
  • 2019-10-30
  • 2011-02-27
  • 1970-01-01
  • 2012-08-26
  • 2023-01-08
  • 2013-04-24
  • 1970-01-01
相关资源
最近更新 更多