如何使 Git“忘记” 已跟踪但现在位于. gitignore 中的文件?

git正在跟踪一个文件,但是现在该文件在.gitignore列表中。

但是,该文件在编辑后一直以git status显示。您如何迫使git完全忘记它?

答案

.gitignore将阻止将未跟踪的文件添加(不add -f )到 git 跟踪的文件集中,但是 git 将继续跟踪已被跟踪的所有文件。

要停止跟踪文件,您需要将其从索引中删除。此命令可以实现。

git rm --cached <file>

如果要删除整个文件夹,则需要递归删除其中的所有文件。

git rm -r --cached <folder>

从主修订版中删除文件将在下一次提交时发生。

警告:虽然这不会从本地删除物理文件,但会在下一个git pull上从其他开发人员计算机删除文件。

下面的一系列命令将删除 Git 索引中的所有项(而不是工作目录或本地存储库中的所有项),然后在遵守 git 忽略的同时更新 Git 索引。 PS。索引 = 缓存

第一:

git rm -r --cached . 
git add .

然后:

git commit -am "Remove ignored files"

或单线:

git rm -r --cached . && git add . && git commit -am "Remove ignored files"

git update-index为我完成了这项工作:

git update-index --assume-unchanged <file>

注意:该解决方案实际上独立于.gitignore因为 gitignore 仅适用于未跟踪的文件。

编辑:自从发布此答案以来,已经创建了一个新选项,应该优先使用。您应该使用--skip-worktree来处理用户不想再提交的已修改跟踪文件,并保持--assume-unchanged的性能以防止 git 检查大跟踪文件的状态。有关更多详细信息,请参见https://stackoverflow.com/a/13631525/717372 ...

git update-index --skip-worktree <file>
git ls-files --ignored --exclude-standard -z | xargs -0 git rm --cached
git commit -am "Remove ignored files"

这将获取被忽略文件的列表,并将其从索引中删除,然后提交更改。

我总是使用此命令删除那些未跟踪的文件。 Unix 风格的单行干净输出:

git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached

它列出了所有被忽略的文件,用引号代替每行输出,以处理内部带有空格的路径,并将所有内容传递给git rm -r --cached从索引中删除路径 / 文件 / 目录。

如果由于其他人可能需要而无法git rm跟踪的文件(警告,即使 git rm --cached ,当其他人获得此更改时,其文件也会在其文件系统中删除)。这些通常是由于配置文件覆盖,身份验证凭据等导致的。请查看https://gist.github.com/1423106了解人们解决该问题的方式。

总结一下:

  • 让您的应用程序查找被忽略的文件 config-overide.ini,并在已提交的文件 config.ini 上使用它(或者,查找〜/ .config / myapp.ini 或 $ MYCONFIGFILE)
  • 提交文件 config-sample.ini 并忽略文件 config.ini,根据需要使用脚本或类似文件复制该文件。
  • 尝试使用 gitattributes clean / smudge magic 来为您应用和删除更改,例如,将配置文件作为替代分支的签出进行涂抹,并清洁配置文件作为 HEAD 的签出。这是棘手的东西,我不建议新手使用。
  • 将配置文件保留在专用于它的部署分支上,该分支永远不会合并到 master。当您要部署 / 编译 / 测试时,您可以合并到该分支并获取该文件。除了使用人工合并策略和 Extra-git 模块外,这实质上是污迹 / 清除方法。
  • 反建议:不要使用假设不变,它只会以眼泪结束(因为 git 自欺欺人会导致不好的事情发生,例如您的更改永远丢失)。

将其移出,提交,然后再移回。这在过去对我有用。可能有一种 “gittier” 方式来完成此任务。

在以下情况下使用此:

1. 您要取消跟踪许多文件,或者

2. 您更新了 gitignore 文件

来源连结: http : //www.codeblocq.com/2016/01/Untrack-files-already-add-to-git-repository-based-on-gitignore/

假设您已经将一些文件添加 / 提交到 git 存储库,然后将它们添加到. gitignore; 中。这些文件仍将存在于您的存储库索引中。本文我们将看到如何摆脱它们。

步骤 1:提交所有更改

在继续之前,请确保所有更改都已提交,包括. gitignore 文件。

步骤 2:从存储库中删除所有内容

要清除您的仓库,请使用:

git rm -r --cached .
  • rm是删除命令
  • -r将允许递归删除
  • –cached仅从索引中删除文件。您的文件仍然在那里。

rm命令可能无法原谅。如果您想事先尝试它的功能,请添加-n--dry-run标志以进行测试。

步骤 3:重新添加所有内容

git add .

步骤 4:提交

git commit -m ".gitignore fix"

您的存储库是干净的:)

将更改推送到您的遥控器,以查看更改是否也在那里生效。

我通过使用git filter-branch实现了这一点。我使用的确切命令来自手册页:

警告 :这将从您的整个历史记录中删除该文件

git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD

该命令将重新创建整个提交历史记录,在每次提交之前执行git rm ,因此将删除指定的文件。不要忘了运行该命令,因为它丢失之前备份。

什么对我不起作用

(在 Linux 下),我想使用此处的帖子建议ls-files --ignored --exclude-standard | xargs git rm -r --cached方法。但是,(某些)要删除的文件的名称中带有嵌入式换行符 / LF / \n 。两种解决方案都没有:

git ls-files --ignored --exclude-standard | xargs -d"\n" git rm --cached
git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached

应付这种情况(获取有关找不到文件的错误)。

所以我提供

git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached
git commit -am "Remove ignored files"

它使用ls-files-z参数和xargs-0参数安全 / 正确地满足文件名中的 “讨厌” 字符。

在手册页git-ls-files(1)中 ,它指出:

不使用 - z 选项时,路径名中的 TAB,LF 和反斜杠字符分别表示为 \ t,\ n 和 \\。

所以我认为如果文件名中包含任何这些字符,则需要我的解决方案。