git 推送在 POST git-receive-pack 后挂起并失败

git push hangs and fails after POST git-receive-pack

我正在尝试推送我的存储库,其中有很多我可以忽略的 .png.mp4.h5 文件。

目录结构:

.gitignore
CV PROJECT
├───.vscode
├───Docker
├───src
│   ├───Game
│   ├───Main
│   │   └───__pycache__  
│   └───Video
│       ├───Images       
│       │   ├───test    
│       │   │   ├───boost # dir that has .png files 
│       │   │   ├───click # dir that has .png files 
│       │   │   └───upgrade # dir that has .png files 
│       │   └───train  
│       │       ├───boost # dir that has .png files 
│       │       ├───click # dir that, has .png files 
│       │       └───upgrade # dir that has .png files 
│       ├───Models # dir that has .h5 files  
│       └───Videos
│           ├───boost # dir that has .mp4 files
│           ├───click # dir that has .mp4 files
│           └───upgrade # dir that has .mp4 files
└───Tutorial
    └───.ipynb_checkpoints

tl;dr 我的 .gitignore 需要什么样子?


命令:

git config --global http.postBuffer 2048M
git config --global http.maxRequestBuffer 1024M
git config --global core.compression 9

git config --global ssh.postBuffer 2048M
git config --global ssh.maxRequestBuffer 1024M

git config --global pack.windowMemory 256m 
git config --global pack.packSizeLimit 256m

# git hangs here
git push --verbose -f origin master

输出:

git 挂在这里:

Total 133 (delta 29), reused 0 (delta 0), pack-reused 0
POST git-receive-pack (569667108 bytes)

所以我试图用这个 .gitignore:

忽略它们
*.mp4
*.h5


Models/*
Videos/*
test/*
train/*

boost/*
upgrade/*
click/*

得到这个输出:

remote: Resolving deltas: 100% (20/20), completed with 1 local object.
remote: warning: File src/Video/Videos/boost/b7.mp4 is 57.86 MB; this is larger than GitHub's recommended maximum file size of 50.00 MB
remote: warning: File src/Video/Videos/click/c7.mp4 is 73.08 MB; this is larger than GitHub's recommended maximum file size of 50.00 MB
remote: warning: File src/Video/Videos/upgrade/u6.mp4 is 56.50 MB; this is larger than GitHub's recommended maximum file size of 50.00 MB
remote: error: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com.
remote: error: Trace: 3a803801864c0608c9e57dd7cf9d3ee3eaca6a180713b3c7119e8b0414c776ee
remote: error: See http://git.io/iEPt8g for more information.
remote: error: File src/Video/medmodel.h5 is 112.78 MB; this exceeds GitHub's file size limit of 100.00 MB
To https://github.com/romhayh/special-mario.git
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://github.com/romhayh/special-mario.git'

在此之后我将 .gitignore 转换为 .gitattributes(不使用 git lfs track)并得到相同的错误消息:

remote: Resolving deltas: 100% (29/29), completed with 1 local object.
remote: warning: File src/Video/Videos/boost/b7.mp4 is 57.86 MB; this is larger than GitHub's recommended maximum file size of 50.00 MB
remote: warning: File src/Video/Videos/click/c7.mp4 is 73.08 MB; this is larger than GitHub's recommended maximum file size of 50.00 MB
remote: warning: File src/Video/Videos/upgrade/u6.mp4 is 56.50 MB; this is larger than GitHub's recommended maximum file size of 50.00 MB
remote: error: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com.
remote: error: Trace: 9add1b6eba287591037b40a5a483a1b7bb9d2746853150a2146bdf83b8e58b9c
remote: error: See http://git.io/iEPt8g for more information.
remote: error: File src/Video/Models/medmodel.h5 is 112.78 MB; this exceeds GitHub's file size limit of 100.00 MB
remote: error: File src/Video/medmodel.h5 is 112.78 MB; this exceeds GitHub's file size limit of 100.00 MB

现实世界的类比在这里很棘手,但假设您有水泥送货服务。您向某个客户交付了 1000 立方码的水泥,这些水泥现在已经凝固。您的客户打电话给您说他们不需要那么多水泥:他们只想要 立方码。所以你让你的卡车再给他们运送 10 码的水泥。你是改善了他们的处境,还是让他们的处境变得更糟?

现在,上述类比的原因很简单:Git 只提交 向存储库添加新内容。如果你将一个巨大的文件放入某个提交中,那么那个巨大的文件就在那个提交中 forever。如果有人不想要那个大文件,而你做了一个 new 提交 缺少 这个大文件,那么,现在你有 两个 提交:一个有巨型文件,一个没有。第二个提交 取决于并因此需要第一个提交 .

无论你做什么,如果你不断添加新的提交,你只会让一切变得更糟。您需要的不是更多水泥(呃,承诺)。您需要某种手提钻和水泥清除服务(从您的存储库中删除 提交的内容)。

但这还不是全部!虽然我们已经看到在 .gitignore 中列出一个文件对任何现有的提交都没有影响——没有任何 existing 提交可以改变,根本;你只需要将它们拖走并完全停止使用它们来摆脱它们——它对 new 提交也没有好的影响,至少 还没有。如果一个文件被跟踪,它在未来提交时对该文件没有影响。

所以:

  • 你的第一项工作是删除一些提交。我们通常使用 git reset 来执行此操作。 git reset命令是破坏性的!在这里要非常小心:您可能应该在您的存储库的 克隆 上工作,而不是原始的。

  • 然后,删除错误提交后,您可能需要显式删除 大文件,这样它们就不再是跟踪。如果文件在 Git 的索引中,则文件在 Git 中 被跟踪 。你怎么知道文件是否在 Git 的索引中?好吧,你知道,因为它被跟踪了。如您所见,这是一种循环问题。 :-) 但是如果你确实想要它-tracked,你可以运行:

    git rm --cached src/Video/Videos/boost/b7.mp4
    

    例如(对于名为 src/Video/Videos/boost/b7.mp4 的文件)。这将从 Git 的索引中删除文件,如果它存在 Git 的索引中(被跟踪),或者会给你一个关于如果文件 没有 存在于 Git 的索引中(未跟踪),则文件不在 Git 中。因此,无论哪种方式,您现在都可以确定该文件是 未跟踪.

当文件 未被跟踪时,git status 通常会抱怨它。 .gitignore 列表让 git status 闭嘴。这通常是 .gitignore 的主要特征:使 git status 表现良好。另一个特点是,只要某些文件当前 未跟踪的,在 .gitignore 中列出该文件就意味着 git add --allgit add * 不会将其添加到Git的索引中,这将使它被跟踪。

某些文件的跟踪性并不是您设置一次就忘记的。因为 commits 是不可更改的,一旦你做了一些提交并且提交 does 有文件,任何时候你使用 git checkoutextract 该提交,文件进入 Git 的索引,因此再次被跟踪。您可以使用 git rm --cached 取消跟踪文件,这样它就不会进入您所做的 new 提交。但是你不能从现有的提交中删除它,永远:没有 existing 提交可以 ever change.

您必须做的是删除 错误的 提交,然后 不再提交这些文件

可以将文件放入Git-LFS,如果您愿意的话。 (Git-LFS 有其自身的怪异和怪癖。我之所以提出这个问题,是因为您在问题中使用 标记并提到了 LFS。)但是您必须摆脱其中包含大文件的现有提交。只有您可以说出这些是哪些提交,因为这些提交在 您的 存储库中,其他人都没有。

这就是为什么我建议您先克隆现有的存储库,然后再尝试删除任何错误的提交。但是,您可能会发现一些其他工具 and/or 方法在这里更有用。参见,例如,How to remove/delete a large file from commit history in Git repository?