完全从Git存储库中删除文件并在GitHub上远程


78

我不小心添加了一个图像文件夹并提交了。然后,我又提交了一个。然后,我使用删除了这些文件git rm -f ./images并再次提交。

现在,我在该分支(master)中进行了更多提交。在我的头上,我没有该./static/images文件夹。

因此,我的回购规模增加了很多。如何完全清除这些斑点?我也想从我的远程GitHub存储库中删除它。


出于某种原因,来自github及以下版本的说明对我不起作用,但是来自“ Pro Git”书中并在此SO答案中引用的答案非常有效:stackoverflow.com/a/16877548/436014-我很好奇关于树过滤器和索引过滤器之间的区别。
waffl 2014年

Answers:


125

这就是您要查找的内容:忽略不会删除文件。我建议您阅读该页面,但这是要使用的特定命令:

git filter-branch --index-filter \
'git rm -r --cached --ignore-unmatch <file/dir>' HEAD

另外,要从git创建的缓存中删除所有已删除的文件,请使用:

rm -rf .git/refs/original/ && \
git reflog expire --all && \
git gc --aggressive --prune

您可以在以下操作中找到有关最后一个命令的更多信息,以及一个可以完成所有操作的脚本:git:永远从历史记录中删除文件或文件夹

另一个带有大量解释的链接:删除敏感数据

[编辑]另外,请参见StackOverflow问题:从Git历史记录中删除敏感文件及其提交

(从natacado上面链接的问题中的答案中复制的命令。)如果您已经从工作副本中删除了文件,则应该可以使用以下文件。找出添加了不需要的文件的提交的哈希。然后做:

git filter-branch --index-filter \
'git update-index --remove filename' <introduction-revision-sha1>..HEAD
git push --force --verbose --dry-run
git push --force

1
您告诉我要做'git rm --cached <file>'。但是,现在,我没有那个“ ./statis/images”文件夹,因为我在项目中有很多领先。在那之后,我也做了很多提交。
Abhijeet Rastogi

1
@shadyabhi Hm,也许尝试在rm命令中添加--ignore-unmatch。让我知道是否可行。
2011年

@Darhuuk我照你说的做了。有很多输出说“ rm ...”。我做了$ git filter-branch --index-filter'git rm -r --cached --ignore-unmatch ./static/images'HEAD然后$ rm -rf .git / refs / original / && git reflog expire- -all && git gc --aggressive --prune。我的存储库仍然是2.7MB。我的资源只有525KB。我的提交只有118个。
Abhijeet Rastogi

@shadyabhi您是否在我链接的另一个StackOverflow问题中尝试了该解决方案?
2011年

@Darhuuk我需要使用rebase吗?我只是所有这些的初学者,所以我没有完全遵循它。
Abhijeet Rastogi

9

您可以重新设置整个分支的基础,并删除添加了图像的提交和删除了图像的提交。

git rebase -i master

您将看到一个提交列表。删除具有要删除的恶意提交的行。(“ dd”在默认编辑器vim中删除一行。然后用ZZ保存)

然后,在自然git垃圾收集过程中将清除悬空的提交,您可以使用Darhuuk答案中给出的命令强制执行此过程。

编辑:即使已推送到远程存储库,此方法也可以使用,但是必须使用--force进行推送。(这同样适用于git filter-branch解决方案)。

请注意,这对于从您的分支机构撤出的任何人都非常烦人。他们应咨询“从上游资源库恢复”


大概是您最初意外添加的图像是您希望保留的提交的一部分。在这种情况下,您需要在重新设置基准期间编辑提交,以拆分出希望保留的部分。您可以通过用“ e”(用于编辑)替换该提交的“ rebase -i”列表中的“ pick”来实现。重新设置过程将在此处停止,您可以使用“ git commit --amend”拆分提交。


4

我本质上是在重复与Windows格式化警告相结合的答案,仅是为了确保它不会作为注释而丢失。

请注意使用双引号而不是单引号,因为这取决于您使用的shell解析字符串的方式。

单线:

git filter-branch --index-filter "git rm -r --cached --ignore-unmatch <file/dir>" HEAD

多行:

git filter-branch --index-filter \
    "git rm -r --cached --ignore-unmatch <file/dir>" HEAD
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.