由于我已经删除了大文件而无法将其推送到GitHub


272

目前我有

  1. 空GitHub回购
  2. SSH服务器存储库(主)
  3. 本地回购

SSH服务器存储库是最新的存储库(生产站点),因此我从那里到本地进行了Git克隆。然后,我尝试git push对GitHub 做一个。

一切正常,但随后又说明了filename.gz对于GitHub而言太大。我不需要此文件,所以我运行了几个Git命令从Git缓存中删除它,然后将其推回SSH服务器。

我没有在本地看到大文件,但是即使git diff什么也没有返回,并且git push返回“一切都是最新的”,它仍然在SSH服务器上-并且即使在我尝试推送到本地文件时,该文件在本地仓库中也不可见GitHub我仍然对此有错误

远程:错误:文件fpss.tar.gz为135.17 MB; 这超出了GitHub的文件大小限制100 MB

我按照GitHub帮助中列出的 “解决问题”下的步骤进行操作,所以这还不够吗?

当文件不在本地或不在git status / diff / push中列出时,文件仍如何在ether中?


2
该文件仍在历史记录中。您需要破坏历史记录,可能是通过压缩添加和删除文件的提交来实现。
Shahbaz

@Shahbaz我按照此站点上“解决问题”下的步骤进行操作……这还不够吗?help.github.com/articles/working-with-large-files
Kevin W.

那里的命令比我对git的了解还要先进,所以我真的无法分辨。无论如何,如果git log -- the_big_file返回任何内容,则该文件仍在历史记录中。
Shahbaz

@Shahbaz不返回任何内容> <
Kevin W.

可能是您还在推送文件所在的其他分支吗?另外,如果文件仍在服务器上,为什么还要git push说所有内容都是最新的呢?由于您更改了历史记录,因此它应该抱怨说无法进行推送,因此您必须强制执行。
Shahbaz 2013年

Answers:


446

您可以使用

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

这将删除该文件历史记录中的所有内容。问题是该文件存在于历史记录中。

此命令更改提交的哈希值,这可能是一个真正的问题,尤其是在共享存储库上。在不了解后果的情况下不应执行此操作。


23
为我工作,但我不得不“强迫”它:git filter-branch --index-filter'git rm -r --cached --ignore-unmatch <file / dir>'-f HEAD
alexoviedo999 2015年

30
此命令更改提交的哈希值,这可能是一个真正的问题,尤其是在共享存储库上。在不了解后果的情况下不应执行此操作。
克里斯,

6
您是否应该用引起问题的文件名或目录名替换<file / dir>?
David Rhoden

12
请注意,如果您要将这些更改应用于所有分支,则需要使用--all标志而不是HEAD
Nick

9
我得到:Rewrite 657560fa18c030bcfac9132ce1c3541e84a5bc2c (1/10) (0 seconds passed, remaining 0 predicted) /usr/lib/git-core/git-filter-branch: 1: eval: Syntax error: end of file unexpected
若昂·阿布兰特什

68

我发现壁球壁球更有用filter-branch。我做了以下事情:

  1. 在本地删除大文件。
  2. 提交本地删除。
  3. 提交的软复位回到X号(对我来说是3) git reset --soft HEAD~3
  4. 然后重新提交所有更改(又称壁球) git commit -m "New message for the combined commit"
  5. 推送压缩的提交。

特殊情况(来自用户@lituo):如果上述方法不起作用,则可能是这种情况。提交1包含大文件,提交1的推送由于大文件错误而失败。提交2删除了大文件,git rm --cached [file_name]但提交2的推送仍然失败。您可以按照上述相同步骤操作,但请使用而不是HEAD~3使用HEAD~2


2
为我工作,只需要在壁球推送成功之前将三个提交的更改重新合并回我的本地存储库即可。
dasWesen

5
这比最佳答案要好得多。最重要的答案搞砸了您的整个提交历史。
manic.coder

没有解决我的问题
Hirak Sarkar

3
到目前为止,这是修复大型未提交或已提交文件而又不完全破坏存储库的唯一答案!Upvoted因此它可以移动到顶部:-)
Ælex

1
@但是我不是包装班:非常感谢!这就像魅力一样工作:)
POOJA GUPTA

61

如果您在寻求帮助之前一直在搞弄仓库,这对我很有帮助。第一种类型:

git status

之后,您应该会看到类似的内容

On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

重要的部分是“ 2次提交”!从这里继续输入:

git reset HEAD~<HOWEVER MANY COMMITS YOU WERE BEHIND>

因此,对于上面的示例,将键入:

git reset HEAD~2

输入后,您的“ git状态”应显示为:

On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

从那里,您可以删除大文件(假设您尚未删除),并且您应该能够重新提交所有文件而不会丢失工作。
我知道这不是花哨的答复,但我希望它能有所帮助!


11
优胜者。简单,干净,有效的git构建解决方案。喜欢这样的答案。
Reece Daniels

3
这是最好的解决方案。
wrahool

40

如果文件是使用您的最新提交添加的,并且尚未推送到远程存储库,则可以删除文件并修改提交,取自此处

git rm --cached giant_file
    # Stage "giant_file" for removal with "git rm"
    # Leave it on disk with "--cached". if you want to remove it from disk
    # then ignore the "--cached" parameter
git commit --amend -CHEAD
    # Commit the current tree without the giant file using "git commit"
    # Amend the previous commit with your change "--amend" 
    # (simply making a new commit won't work, as you need
    # to remove the file from the unpushed history as well)
    # Use the log/authorship/timestamp of the last commit (the one we are
    # amending) with "-CHEAD", equivalent to --reuse-message=HEAD
git push
    # Push our rewritten, smaller commit with "git push"

1
由于该文件不再位于git索引中,因此此解决方案将无法正常工作(它会untrackedgit status..的文件列表形式出现。
loretoparisi

没事 应用此选项后,它减少了文件总数,但在显示进程99%之后,它再次卡住。有什么建议我想念的吗?
CoDe

4
-CHEAD是什么意思?
艾林

1
如果我想从特定的提交而不是最后一次提交尝试呢?我试过了,git rm --cached giant_file commit_id但是没有用:(
puifais

@puifais我将还原到上一个提交,执行这些步骤,然后与当前提交合并。我不确定这是否是最好的方法,我不是Git专家
BlueMoon93

13

我有一个类似的问题,并使用上述步骤删除了文件。效果很好。

然后,我需要删除的第二个文件出现错误: remote: error: File <path/filename> is 109.99 MB; this exceeds GitHub's file size limit of 100.00 MB

我尝试了相同的步骤,但出现错误: "A previous backup already exists in <path/filename>"

通过对该网站的研究,我使用了以下命令:git filter-branch --force --index-filter "git rm --cached --ignore-unmatch <path/filename>" --prune-empty --tag-name-filter cat -- --all

效果很好,大文件被删除。

令人难以置信的是,推送仍然失败,并出现另一个错误: error: RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 104 fatal: The remote end hung up unexpectedly

我通过直接修改.git配置文件来解决此问题- postBuffer = 999999999

在那之后,一切顺利了!


1
我不得不抗拒删除一个大文件(如上所述)的另一个陷阱是,其中一个文件夹中包含#号字符。对于正常的git操作,这根本没有问题,但是对于git rm我来说,我需要提供文件的完整存储库路径名,并使用反斜杠转义#使其正常工作
jacanterbury

这也对我有用。我reset hard通过一次简单的推送就避免了页面底部的步骤。 czettner.com/2015/07/16/…–
蒙特·海沃德

这在还运行了“ git push -f origin”之后
起作用

12

为什么即使删除了大文件,GitHub为什么仍拒绝我的回购?

Git会存储项目的完整历史记录,因此,即使您从项目中“删除”文件,Git存储库在其历史记录中仍会保留该文件的副本,并且如果您尝试推送到另一个存储库(例如托管于的存储库)然后,Git 要求远程存储库具有与本地存储库相同的历史记录(即,其历史记录中包含相同的大文件)。

我怎样才能让GitHub接受我的仓库?

您需要在本地清理项目的Git历史记录,从所有历史记录中删除不需要的大文件,然后再使用以后的“清理过的”历史记录。受影响的提交的Git提交ID将更改。

如何从Git存储库中清除大文件?

BFG Repo-Cleaner清除 Git历史记录中不需要的大文件的最佳工具-它是一种git-filter-branch专门为从Git历史记录中删除不需要的文件而设计的更简单,更快捷的选择。

认真遵循使用说明,核心部分就是这样:

$ java -jar bfg.jar --strip-blobs-bigger-than 100M my-repo.git

任何大小超过100MB的文件(不在您的最新提交中)都将从Git存储库的历史记录中删除。然后,您可以git gc用来清除无效数据:

$ git gc --prune=now --aggressive

BFG通常比运行速度快至少10-50git-filter-branch,并且通常更易于使用。

完全公开:我是BFG Repo-Cleaner的作者。


1
我的病例还有其他并发症,无法压扁。BFG工具效果很好。谢谢。
dantopa

这是一个
了不起的

4

我遇到了同样的问题,没有答案对我有用。我通过以下步骤解决了:

1.查找哪些提交包含大文件

git log --all -- 'large_file`

最低的提交是结果列表中最早的提交。

2.找到最老的一个。

git log

假设您得到了:

commit 3f7dd04a6e6dbdf1fff92df1f6344a06119d5d32

3. Git变基

git rebase -i 3f7dd04a6e6dbdf1fff92df1f6344a06119d5d32

温馨提示

  1. 项目清单
  2. 我只是选择drop包含大文件的提交。
  3. 在对基准进行修复的过程中,您可能会遇到冲突,并使用它git rebase --continue来继续直到完成为止。
  4. 如果在重新设置基准期间发生任何问题,请使用git rebase --abort取消它。

4

我已经尝试了所有上述方法,但是它们都不适合我。

然后我想出了自己的解决方案。

  1. 首先,您需要一个干净的最新本地存储库。删除所有该死的大文件。

  2. 现在,在您的repo文件夹的外部创建一个新文件夹,并使用“此处的Git创建存储库”将其设为新的Git存储库,我们将其称为new_local_repo。就是这个!以上所有方法都说您必须清除历史记录...,嗯,我对此感到厌烦,让我们创建一个完全没有历史记录的新回购!

  3. 将文件从旧的,搞砸了的本地存储库复制到新的,漂亮的存储库。请注意,文件夹图标上的绿色徽标将消失,这很有希望,因为这是一个新的仓库!

  4. 提交到本地分支,然后推送到远程新分支。我们称其为new_remote_branch。如果您不知道如何从新的本地存储库中推送,请使用Google。

  5. 恭喜!您已将干净的最新代码推送到GitHub。如果不再需要远程主分支,则可以将new_remote_branch设置为新的主分支。如果您不知道该怎么做,请使用Google。

  6. 下一步,是时候删除该死的旧本地存储库了。将来,您仅使用new_local_repo。



1

将大文件/文件夹保留在工作文件夹中的解决方案

这是用于解决此处要求的问题的行(来自答案1):

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

如果文件/目录在工作树中,则此命令还会删除该文件/目录。

如果要将文件/文件夹保留在工作树中,我建议采取以下步骤。

  1. 该错误运行后 git reset HEAD^
  2. 将有问题的文件/文件夹添加到.gitignore`文件中。

  3. 照常进行git add .,这可能会捕获其他文件/文件夹,但必须捕获.gitignore文件。接下来是git commit -m"message"最后git push origin <branch_name>


0

这对我有用。来自github Squashing Git的文档提交git reset origin / master

git checkout master && git pull;
git merge feature_branch;
git add . --all;
git commit -m "your commit message"

此处查找文档


0

我正在添加第一个答案。

git filter-branch --index-filter'git rm -r –cached --ignore-unmatch'头

来自原始服务器/主服务器的合并冲突。

您的分支和“来源/主”已经分歧,分别具有114和109个不同的提交。(使用“ git pull”将远程分支合并到您的分支中)

请运行这个

git reset-硬来源/主

它会丢弃我所有已上演和未上演的更改,忘记我当前本地分支上的所有内容,并使它与原点/原版完全相同。


0

因此,我遇到了一种特殊情况:我从gitlab克隆了一个存储库,该存储库包含一个大于100 mb的文件,但是在git历史记录中的某个时候被删除了。然后稍后,当我添加一个新的github私有仓库并尝试推送到新仓库时,我得到了臭名昭著的“文件太大”错误。至此,我不再可以访问原始的gitlab存储库。但是,我仍然可以bfg-repo-cleaner在计算机上的LOCAL存储库上使用新的私有github 存储库:

$ cd ~
$ curl https://repo1.maven.org/maven2/com/madgag/bfg/1.13.0/bfg-1.13.0.jar > bfg.jar
$ cd my-project
$ git gc
$ cd ../
$ java -jar bfg.jar --strip-blobs-bigger-than 100M my-project
$ cd my-project
$ git reflog expire --expire=now --all && git gc --prune=now --aggressive
$ git remote -v # confirm origin is the remote you want to push to
$ git push origin master

0

有时文件会保留在跟踪历史记录中,请尝试以下步骤:

  1. git commit,如果您看到列出了大文件的创建模式,请执行以下操作:
  2. git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch filename' HEAD。您应该在控制台中看到一堆Rewrites,其结尾为:

    rm'文件名'和

    最后一行Ref被重写。

完成。

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.