如何删除.gitignore中列出但仍在存储库中的文件?


327

我的存储库中有一些文件应忽略,我将它们添加到.gitignore中,但是,当然,它们不会从我的存储库中删除。

所以我的问题是,是否存在使用filter-branch的魔术命令或脚本可以重写我的历史记录并轻松删除所有这些文件?或者只是一个将创建删除操作的命令?





警告:虽然这不会从本地删除物理文件,但会在下次git pull时从其他开发人员的计算机删除文件。如何使Git“忘记”已跟踪但现在位于.gitignore中的文件?
克里斯·罗夫

@Stevoisiak,这不是该问题的重复,因为该问题询问所有被忽略的文件,并且比任何类似问题都有更好的答案。
Omn

Answers:


438

您可以从存储库中手动删除它们:

git rm --cached file1 file2 dir/file3

或者,如果您有很多文件:

git rm --cached `git ls-files -i --exclude-from=.gitignore`

但这似乎不适用于Windows上的Git Bash。它产生一条错误消息。以下效果更好:

git ls-files -i --exclude-from=.gitignore | xargs git rm --cached  

关于在没有这些文件的情况下重写整个历史记录,我高度怀疑是否存在自动方法。
我们都知道改写历史是不好的,不是吗?:)


2
不幸的是,Windows上的Git Bash命令不适用于包含空格的路径
Nate Bundy 2014年

19
@Cupcake谢谢。git ls-files -i -z --exclude-from=.gitignore | xargs -0 git rm --cached似乎可以解决问题
Nate Bundy 2014年

3
我在Windows上遇到了同样的问题。我正在使用powershell,在我的情况下,我收到了@ samy-dindane提示的第三个命令,并将其更改为foreach。变成了这个git ls-files -i --exclude-from=.gitignore | %{git rm --cached $_}
digaomatias 2014年

1
“ git ls-files -i --exclude-from = .gitignore”非常有用,它告诉我.ignore排除了哪些文件。
欧文·曹

1
我很高兴找到这些命令,但是它并没有真正从存储库中删除文件。当我删除2300 kB的图像时,存储库大小仅下降了10 kB。因此,例如,不能使用它来使存储库更小且传输更快。
JanPotužník'19

343

在任何操作系统上工作的更简单方法是

git rm -r --cached .
git add .
git commit -m "Removing all files in .gitignore"

您基本上读取了所有文件,.gitignore中的文件除外


1
这对回购中其他用户执行拉动有何影响-当我阅读它时,我们不再要跟踪的文件夹被删除了???我们如何才能防止这种情况-我们只想取消跟踪
snh_nl

这将使用伪造的提交消息将所有文件标记为已更改!
Haidar Zeineddine

3
假提交消息是什么意思?这是一条真正的提交消息:P当然,您可以根据自己的需要更改该消息...
gtatr

1
为了完整起见,您最后需要git push命令。
Mariusz Bialobrzeski

1
不这样做,它会删除历史上的所有文件
agrath

144

由于未跟踪.gitignore中的文件,因此可以使用git clean命令以递归方式删除不受版本控制的文件。

使用git clean -xdn进行试运行,看看将被删除。
然后使用git clean -xdf执行它。

基本上,git clean -hman git-clean(在Unix中)将为您提供帮助。

请注意,此命令还将删除暂存区域中没有的新文件

希望能帮助到你。


6
这应该是公认的答案。它实际上有效(在macOS上,可接受的答案对我不起作用),而且更干净。
罗杰·欧巴

25
这个答案是不适用-在OP说,文件.gitignore 被跟踪。
肯·威廉姆斯

20
谨防!这将永久删除所有未跟踪的文件,而不仅仅是从分支中删除
Emmanuel '18

1
git clean -xdn是不会删除的试运行。下一个会。
JohnZaj

17
-1:这是一个极具误导性的答案-原始海报想要从存储库中删除,而不是完全删除文件。我已经快要删除IDE所需的动态文件负载,而并非要求将其包含在存储库中。
奥义峰'18

4

通过使用sed处理.gitignore语句的输出,我做了一个非常简单的解决方案:

cat .gitignore | sed '/^#.*/ d' | sed '/^\s*$/ d' | sed 's/^/git rm -r /' | bash

说明:

  1. 打印.gitignore文件
  2. 从印刷品中删除所有评论
  3. 删除所有空行
  4. 在行首添加'git rm -r'
  5. 执行每一行。

10
sed简单吗?
IgorGanapolsky

0

在Linux中,您可以使用以下命令:

例如,我想删除“ * .py〜”,因此我的命令应为==>

find . -name "*.py~" -exec rm -f {} \;


-3

将git添加到.gitignore后,它将忽略与.gitignore模式匹配的文件。

但是存储库中已经存在的文件仍将保留。

用于git rm files_ignored; git commit -m 'rm no use files'删除忽略的文件。


4
它们很多,有没有一种方法可以删除它们而不必指定它们的名称?
无畏的2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.