题 如何让Git“忘记”一个被跟踪但现在位于.gitignore的文件?


有一个文件被跟踪 git,但现在文件在 .gitignore 名单。

但是,该文件不断出现 git status 经过编辑。你怎么用力 git 彻底忘掉它?


3665
2017-08-13 19:23


起源


git clean -X 听起来很相似,但它不适用于这种情况(当Git仍在跟踪文件时)。我正在为寻求不遵循错误路线的解决方案的人写这篇文章。 - imz -- Ivan Zakharyaschev
唯一真正的答案是下面,见 git update-index --assume-unchanged。此解决方案1)将文件保留在服务器(索引)上,2)允许您在本地自由修改它。 - Qwerty
你需要使用 --skip-worktree,见: stackoverflow.com/questions/13630849/... - Doppelganger
一个重要的问题是:文件是否应保留在存储库中?例如,如果某人新克隆了回购,他们是否应该获得该文件?如果 是 然后 git update-index --assume-unchanged <file> 是正确的,文件将保留在存储库中,并且不会添加更改 git add。如果 没有 (例如,它是一些缓存文件,生成的文件等),然后 git rm --cached <file> 将从存储库中删除它。 - Martin
@Martin @Qwerty Everyon应该停下来提出建议 --assume-unchanged 这是为了防止git检查大型跟踪文件的状态,但更喜欢 --skip-worktree 这是用于不再想要提交的已修改跟踪文件。看到 stackoverflow.com/questions/13630849/... - Philippe


答案:


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

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

git rm --cached <file>

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


3887
2017-08-13 20:40



为我工作的过程是1.首先提交挂起的更改2. git rm --cached <file>并再次提交3.将文件添加到.gitignore,检查git status并再次提交 - mataal
非常重要的补充。如果被修改的文件将被修改(但是尽管这应该没有提交),在修改和执行之后 git add . 它将被添加到索引中。下一次提交会将其提交到存储库。为了避免这种情况,在所有mataal再说一个命令后立即执行: git update-index --assume-unchanged <path&filename> - Dao
@AkiraYamamoto的方法也适合我。在我的情况下,我压缩了输出,因为我的存储库有数千个文件: git rm -r -q --cached . - Aaron Blenkush
这将删除该文件 git pull 虽然。 - Petr Peller
git rm --cached <file>只是从存储库中删除文件,git update-index --assume-unchanged <file>未显示未更改的文件中的文件,并且不会进行新的更改。但我想要GIT J NOT IGNORE内容文件PLEEEEEASE - Igor Semin


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

第一:

git rm -r --cached . 
git add .

然后:

git commit -am "Remove ignored files"

1997
2017-09-30 13:51



要突出显示此答案与已接受答案之间的区别:使用此命令您无需实际知道受影响的文件。 (想象一下临时目录,其中包含许多随机文件,应该从索引中清除)。 - Ludwig
与接受的答案相同。文件将被删除 git pull。 - Petr Peller
将此作为标准git命令会很好。就像是 git rmignored。 - Berik
@gudthing -r代表“递归” - Monkey King
有了这个,你最终可能会添加 其他 当前不在的无用文件 .gitignore。如果取决于您的噪音,可能很难找到 git status 是在这个命令之后。一个命令 只删除 新忽略的文件会更好。这就是我喜欢的原因 thSoft的回答 - KurzedMetal


git update-index 为我做的工作:

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

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

编辑: 由于此答案已过帐,因此创建了一个新选项,应该首选。你应该用 --skip-worktree 这是用于不再需要提交并保留的已修改跟踪文件 --assume-unchanged 用于防止git检查大型跟踪文件状态的性能。看到 https://stackoverflow.com/a/13631525/717372 更多细节...


740
2017-11-27 11:24



这个 IS 真正的答案。实际上很棒,非常简单,不会污染 git status 实际上非常直观。谢谢。 - Pablo Olmos de Aguilera C.
我走得很好 rm [...] . 解决方案,至少我可以理解它是如何工作的。我找不到什么很好的文档 update-index & --assume-unchanged 做。任何人都可以添加这个与另一个相比的方式,因为我想删除所有被忽略的文件吗? (或清楚解释的链接?) - Brady Trainor
git update-index --assume-unchanged <path> … 将导致git忽略指定路径中的更改,无论如何 .gitignore。如果您从远程执行并且该远程对此路径进行了更改,则git将使合并失败,并且您需要手动合并。 git rm --cached <path> … 会导致git停止跟踪该路径。如果您不添加路径 .gitignore 你会看到未来的道路 git status。第一个选项在git提交历史记录中具有较少的噪声,并允许在将来分发对“忽略”文件的更改。 - ManicDee
使用以下命令撤消:git update-index --no-assume-unchanged <file> - xgMz
我很困惑这不是可接受的答案。这里接受的答案显然不是回答被问到的实际问题。此答案忽略对存储库中文件的更改,同时不将其从存储库中删除。 - Dave Cooper


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

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


218
2018-05-23 22:29



如果您还需要从工作目录中删除它们,那么只需运行即可 git ls-files --ignored --exclude-standard | xargs git rm 。我相信这个答案是最好的!因为它非常清楚,以Unix方式,并且以直接的方式完成所需的事情,而不构成其他更复杂的命令的副作用。 - imz -- Ivan Zakharyaschev
很好的答案;但是,如果中间有空格的路径,则命令将失败,例如:“My dir / my_ignored_file.txt” - David Hernandez
git ls-files --ignored --exclude-standard | sed's /.*/"&"/'| xargs git rm --cached - David Hernandez
git rm 会抱怨如果 ls-files 什么都不匹配使用 xargs -r git rm ... 告诉 xargs 不要跑 git rm 如果没有文件匹配。 - Wolfgang
最好使用\ 0作为分隔符: git ls-files --ignored --exclude-standard -z|xargs -0 git rm --cached - Nils-o-mat


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

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

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


60
2018-06-19 15:42



好方案!完美工作,感觉更正确,删除所有文件,然后重新添加。 - Jon Catmull
我也发现这个“最干净”。这可能很明显,但只是运行第一部分, git ls-files --ignored --exclude-standard,它本身可以让你先了解/验证你的新文件 .gitignore 在您继续执行决赛之前,将要排除/删除 git rm。 - JonBrave
请注意,文件名失败,其中包含某些“令人讨厌”的字符,例如 \n。我已发布我的解决方案以满足此需求。 - JonBrave
另一个警告:在拉动时,这将导致文件被删除在其他人的工作目录中,对吧? - LarsH


如果你不能 git rm 跟踪文件,因为其他人可能需要它(警告,即使   git rm --cached,当其他人得到此更改时,他们的文件将在其文件系统中删除)请查看 https://gist.github.com/1423106 了解人们解决问题的方法。


49
2017-07-19 00:08



git不会删除该文件,如果它在删除时是脏的。如果它不脏,检索文件就像这样简单 git checkout <oldref> -- <filename>  - 但随后它会被检出并被忽略。 - amenthes
虽然理论上这可以回答这个问题, 这会更好 在这里包括答案的基本部分,并提供参考链接。看到 这里 有关如何编写的说明 更好 “基于链接”的答案。谢谢! - GhostCat
只是说。 5岁的答案和45个赞成票,但没有人敢说“链接只有答案是坏的?” - GhostCat


将它移出,提交,然后将其移回。这在过去对我有用。实现这一目标可能有一种“轻微”的方式。


44
2017-08-13 19:27



如果您想忽略之前未被忽略的一堆文件,这非常有用。虽然像你说的那样,但可能有更好的方法。 - Oskar Persson
这正是我所做的。只需将文件移动到git之外的文件夹,然后执行“git add。”,“git commit”。 (这删除了文件)然后添加gitignore,引用文件/文件夹,再次提交将gitignore文件添加到git,然后复制/移回文件夹,它们应该被忽略。注意:看起来文件是从GIT中删除的,所以可能会将它们从其他结账/拉出中删除,如上面的解决方案所述,但由于你最初正在制作它们的副本,这不是一个问题恕我直言。让团队的其他成员知道...... - Del
这是摆脱错误提交文件夹的最简单方法。 - Martlark
似乎是我能看到的唯一途径。在git中,这是一个巨大的错误(不是“功能”),只要你向.gitignore添加一个文件/文件夹,它就不会从那时起永远忽略那个文件 - 无处不在。 - JosephK


什么对我不起作用

(在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

这使用了 -z 论证 LS-文件,和 -0 论证 xargs的 安全/正确地迎合文件名中的“讨厌”字符。

在手册页中 GIT-LS-文件(1), 它指出:

如果未使用-z选项,则使用TAB,LF和反斜杠字符   路径名分别表示为\ t,\ n和\\。

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

编辑:我被要求添加 - 像任何一样 git rm 命令---必须跟着一个 承诺 使删除永久化,例如 git commit -am "Remove ignored files"


37
2017-12-29 12:50



对我来说这是最好的解决方案。它具有比a更好的性能 git add .。它还包含上述一些评论的最佳改进。 - Nils-o-mat
很好的解决方案,效果很好 - smac89
处理了一个处理 - 删除了正确名称空格的文件。 - Dave Walker
你能添加thSoft吗? git commit -am "Remove ignored files" 之后你的回答?你的答案结合起来让我了解事情:j - kando