2017-10-17 155 views
0

我已经添加文件> 100 Mb到我的git仓库,它在本地git中工作。不幸的是,github有100 MB的限制。无法从git存储库中删除文件?

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

不幸的是,我仍然无法推送到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 

失败如何删除文件W/O指定给它确切的路径?

UPDATE

我试图运行

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 
+1

https://rtyley.github.io/bfg-repo-cleaner/ – Sirko

+0

你可以创建一个新的分支,拉最新的,并从当地移除然后puush到主? – AK47

+1

或多一点上下文:https://help.github.com/articles/removing-sensitive-data-from-a-repository/ – Boldewyn

回答

1

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

几种方法可以做到这一点是:

  • ,如果你有一个相当低的数目提交的编辑:
    使用git rebase -i手动编辑提交
  • ,如果你有做大规模(许多提交,几个分支): 使用git filter-branch --index-filter
    或@Sirko
建议

如何使用git变基-i:

如果你的历史是这样的:

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

返工B的内容,则需要从其父变基:

git rebase -i A 

这将打开一个文本编辑器,它会询问您要对从BF的每次提交执行什么操作

它将开始:

pick B message 
pick C message 
pick D message 
... 

你想改变B,除去从这个大的文件提交

# set the action on b to 'edit' (or e) : 
e B message 
pick C message 
pick D message 
... 

保存并关闭。

现在git会运用你告诉他的行动:

  • 他会倒带你的回购高达A
  • 你告诉git的编辑B:他将适用B,然后停止,以便您可以做任何你想做
  • 删除从此大文件提交:

    git rm --cached big/file 
    git commit --amend 
    
  • 现在你要告诉git的恢复与重订基期:

    git rebase --continue 
    
  • 你应该看到说明git的消息是重播C,那么d ..达到F

+0

'git rebase -i'打开带有'.git/rebase-merge/git-rebase-todo'文件的文本编辑器 – Dims

+0

我显示2个提示(为什么是2?我有几十个) '在每一行的开始处写一个字;如果我用'drop'替换一个'pick'并保存文件,则表明'不能应用...,当你解决了这个问题' – Dims

+0

你是否在特定的提交中添加了大文件? – LeGEC

0

的文件仍然是在仓库的历史...您需要删除提交(S)介绍了吧...

如果你能清晰地识别提交介绍了它,那么请尝试以下操作:

git rebase -i ${COMMIT_ID}^ 

这将显示提交列表,您可以选择editdrop某些项目。通过将缺省的pick替换为drop来简单地删除它(和所有其他更改,即提交所做的更改!),或者使用edit标记违规提交,删除文件,重新提交并确认,标记违规提交。

完成此操作后,请再试一次。


Git是不是真的专为大型二进制文件,这样避免了检查它们。 如果“需要”来,那么它可能是值得一试的Git Large File Storage项目。

+0

什么是'$ {COMMIT_ID} ^'? – Dims

+0

当您执行'git log'时,您会看到列出的提交ID以及提交消息和其他信息。你应该用这个标识符替换'$ {COMMIT_ID}',然后用帽子('^')表示“_the parent of_”。例如'git rebase -i f928b95 ^'。 – Attie

1

顺便说一句,删除文件完全是最简单的选择(虽然你看,这不完全是简单的),前提是你不需要的文件在您的回购协议。另一个选择是使用像git lfs这样的工具来允许你的仓库引用文件,而不需要直接将文件放入你的仓库。这解决了与git中的大文件相关的许多问题,如果您确实需要该文件,应该考虑这些问题;但重写回购使用lfs为一个已经提交的文件是另一个完整的话题...

所以,回到删除的问题。为了提供多一点背景:

Git中有三个地方的文件会被发现。

1)工作树木 - 仅仅是纯文本文件,你努力。 git没有特别的努力来保存这里的数据,它只存在于本地。您可以通过git以外的方式或使用git rm(特别是如果您还需要将其从索引中删除)从这里删除文件。

2)索引 - 这是“分阶段”进行新提交的文件。当你说git add你更新索引。 git将挂在这里独立于工作副本的数据,但仍然只是本地的,并没有特别的努力来保存历史。 git rm将从索引中提取文件。

3)数据库 - 这是你的项目的历史存在。当你说git commit时,将表示项目的“对象”添加到数据库中。该数据库是git保留历史,你必须走出去的方式,使git从这里丢失任何数据。数据库基本上是在pushfetch操作期间在回购期间共享的内容。 git rm对数据库没有影响。

现在,正如其他人所指出的,因为你已经创建了一个提交包含文件,你需要做的比git rm多。第一步是重写任何包含提交文件的提交文件的历史记录。

有人说你需要解决的承诺是“介绍”的文件;这是误导。您需要处理全部对该文件的引用(或者在技术上,对代表该文件的BLOB对象)。

因为rebase解释,相对于他们的父母他们的变化方面承诺,它可以在一个相对便捷的方式处理这个问题,如果的不是很多分支与合并加入的文件后发生的情况。例如,如果文件是在提交A中创建的,并且唯一可以访问A的引用是master,并且在master中没有合并提交比A更新,那么rebase是最简单的解决方案。假设A不是根提交,

git rebase -i A^ master 

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

git rebase -i --root master 

在弹出待办列表,您更改A编辑命令,给出的提示进行编辑时提交你删除文件,然后告诉rebase继续。

在这一点上,可能git push将工作,因为git不必发送整个数据库;它只是发送你告诉它推的参考文献的历史。但不要混淆:你仍然尚未从本地数据库中删除文件。要做到这一点,你必须确保没有任何东西(即使是reflog)可以到达该文件,然后使用git gc。如果您已成功从所有裁判的历史记录中删除该文件,则最终会发生这种情况;这可能是文件,除非你受限于本地存储。

在上述过程中有几个重要的假设,如果您刚刚提交了这些假设可能存在的文件。但是如果存在多个分支可以达到承诺A,并且/或者如果有合并提交可以达到A,那么执行rebase会变得更加困难。那时你会看到git filter-branchBFG Repo Cleaner作为解决方案。在这两项中,BFG对于这项任务来说要简单得多,速度更快;如果你搜索它,你可以找到许多来源(包括一些SO条目),概述了它的用法。因为filter-branch更通用,所以使用起来更加困难,但它又是“内置”的 - 无需下载其他软件。

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

相关问题