无法从git存储库中删除文件?

时间:2017-10-17 11:38:07

标签: git github delete-file

我已将文件> 100 Mb添加到我的git存储库,它在本地git中工作。不幸的是,github有100 Mb的限制。

所以,我重写了代码,以便它不需要这个大文件,然后删除它,然后提交。

不幸的是,我仍然无法推送到gothub,因为文件仍在存储库中。

我试图运行

git rm --cached my_file.dat

git rm --cached -r my_file.dat

git rm --cached mypath/my_file.dat

并且所有命令都以

失败
fatal: pathspec ... did not match any files

如何删除没有指定确切路径的文件?

更新

我试图运行

java -jar bfg.jar --strip-blobs-bigger-than 100M

并且消息失败

Scanning packfile for large blobs completed in 2 ms.
Warning : no large blobs matching criteria found in packfiles - does the repo need to be packed?

但仍无法

git push origin master

File my_path/my_file.dat is 257.62 MB; this exceeds GitHub's file size limit of 100.00 MB

3 个答案:

答案 0 :(得分:1)

您需要以某种方式从所有提交中删除此文件。

有几种方法可以做到:

  • 如果编辑的提交数量相当少:
    使用String file_names[]= null; if (sizeOfFiles < 1) { file_names = new String[]{"No recent files.\nTouch New to add files."}; ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.file_list, file_names); listView.setAdapter(adapter); } else if (sizeOfFiles == 1) { file_names = new String[]{filesList[sizeOfFiles - 1].getName()}; ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.file_list, file_names); listView.setAdapter(adapter); } else if (sizeOfFiles == 2) { file_names = new String[]{filesList[sizeOfFiles - 1].getName(), filesList[sizeOfFiles - 2].getName()}; ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.file_list, file_names); listView.setAdapter(adapter); } 手动编辑提交
  • 如果你必须大规模地进行(许多提交,几个分支): 使用git rebase -i
    或@Sirko建议的git filter-branch --index-filter

如何使用git rebase -i:

如果您的历史记录如下:

bfg-repo-cleaner

要重新编写B的内容,您需要从其父级重新定义:

      big file added here
        v
--*--A--B--C--D--E--F <- master

这将打开一个文本编辑器,该编辑器将询问您要对从git rebase -i A B

的每次提交执行哪些操作

它将从:

开始
F

您想要更改 pick B message pick C message pick D message ... ,以从此提交中删除大文件

B

保存并关闭。

现在git将应用你告诉他的行动:

  • 他会将你的回购卷回到# set the action on b to 'edit' (or e) : e B message pick C message pick D message ...
  • 你告诉git编辑A:他将申请B,然后停止以便你可以做任何你想做的事情
  • 从此提交中删除大文件:

    B
  • 现在你想告诉git继续使用变基:

    git rm --cached big/file
    git commit --amend
    
  • 你应该看到消息表明git正在重播C然后D ..直到F

答案 1 :(得分:1)

顺便说一句,直接删除文件是最简单的选择(虽然你看,它并不完全简单),只要你不需要你的仓库中的文件。另一种选择是使用git lfs之类的工具来允许您的仓库引用该文件,而无需将文件直接放入您的仓库中。这解决了git中与大文件相关的许多问题,如果您确实需要该文件,则应予以考虑;但是重写一个repo以使用lfs来表示已经提交的文件是另一个完整的话题......

所以,回到删除的问题。提供更多背景信息:

在git中,有三个地方可以找到文件。

1)工作树 - 只是您处理的普通文件。 git不会在此处保留数据,并且只在本地存在。您可以通过git之外的方式或使用git rm从这里删除文件(特别是如果您还需要从索引中删除它们)。

2)索引 - 这是文件&#34; staged&#34;进行新的提交。当您说git add时更新索引。 git将独立于工作副本挂在此处的数据,但它仍然只是本地的,并且没有特别的努力来保存历史。 git rm将从索引中取出一个文件。

3)数据库 - 这是您的项目历史存在的地方。当你说git commit时你添加&#34;对象&#34;代表您的数据库项目。数据库是git保存历史记录的地方,您必须尽量让git从此处丢失任何数据。数据库基本上是在pushfetch操作期间在回购之间共享的内容。 git rm对数据库没有影响。

现在正如其他人所说,因为你创建了一个包含该文件的提交,所以你需要做的不仅仅是git rm。第一步是重写包含包含该文件的提交的任何引用的历史记录。

有人说你需要解决&#34;介绍&#34;文件;那是误导性的。您需要处理对文件的所有引用(或者,技术上,处理代表该文件的BLOB对象。)

因为rebase根据他们相对于父母的变化来解释提交,所以它可以以相对方便的方式处理这个,如果那里没有很多分支和在添加文件后继续合并。例如,如果文件是在commit A中创建的,并且A可以访问的唯一ref是master,并且没有比{{1更新的合并提交在A中,master是最简单的解决方案。假设rebase不是根提交,

A

(其中git rebase -i A^ master 是引入文件的提交的SHA);但如果A^是根提交,意味着A无效,那么

A^

在弹出的TODO列表中,您将git rebase -i --root master 的命令更改为编辑,并在给出提示编辑提交时删除文件,然后告诉A继续。

此时rebase可能会有效,因为git push不必发送整个数据库;它只是发送你告诉它推送的ref的历史。但请不要感到困惑:您仍未从本地删除数据库中的文件。为此,您必须确保没有任何内容(甚至是reflog)可以访问该文件,然后使用git。如果您已成功删除所有参考文件中的文件。历史,这最终会发生;这可能是文件,除非你限制在本地存储。

上述程序中有几个重要的假设,如果您刚刚提交了该文件,那么这些假设可能会成立。但是,如果存在可以达到提交git gc的多个分支,和/或如果存在可以从A进行的合并提交,那么执行A会变得更加困难。当您查看rebasegit filter-branch作为解决方案时,那就是这样。在这两项任务中,BFG Repo Cleaner更简单,更快捷;如果你搜索它,你可以找到很多来源(包括一些SO条目),概述它的用法。由于BFG更具通用性,因此难以正确使用,但之后又会内置&#34;内置&#34; - 无需下载其他软件。

所有这些技巧都会重写历史记录。由于您无法推送现有的历史记录,这可能不是什么大问题(假设您没有第二个遥控器,您已经推动了这些更改)。

答案 2 :(得分:0)

该文件仍在存储库的历史记录中...您需要删除引入它的提交...

如果您可以清楚地识别引入它的提交,请尝试以下操作:

git rebase -i ${COMMIT_ID}^

这会向您显示提交列表,您可以在其中选择editdrop个特定项目。通过将默认pick替换为drop来标记违规提交,只需将其删除(以及提交所做的所有其他更改!),或使用{标记违规提交{1}},删除文件,重新提交并继续。

完成此操作后,请尝试再次按下。

Git并非真正适用于大型二进制文件,因此请避免检入它们。 如果你需要&#34;那么,可能值得查看Git Large File Storage项目。