GitHub git push 推送大文件
一、增加 Git 的 HTTP 缓冲区
GitHub 对提交的文件大小做了限制,GitHub 会阻止超过100 MB的推送(单文件)
为此可以将缓冲区设置为 500MB,全局配置和当前仓库配置命令分别如下:
# 全局配置
# http.postBuffer默认单位为B(字节),500MB = 1024*1024*500
git config --global http.postBuffer 524288000
# 当前仓库配置
git config http.postBuffer 524288000
如果需要推送的文件非常大,可以将这个值设置得更大,例如 1048576000
(1GB)
二、使用 Git LFS (Large File Storage)
方法一容易超时被拒,如果不成功可以考虑方法二,使用 Git LFS 来进行管理
1. 查询超过 100m 的文件
首先右键项目文件名选择打开 Git bash here,然后查询超过 100m 的文件名,命令如下:
find ./ -size +100M
例如,查询到超过 100m 的文件名如下所示:
2. 撤销上次提交
由于 git push 失败了,远程仓库(GitHub)上的代码没有被更新修改,但需要撤销在本地执行的 git commit,可以使用 git reset 命令(会移动 HEAD 指针,但可以保留代码修改),具体命令如下:
git reset HEAD~1
3. 下载安装 Git LFS
打开并访问Git LFS 官网,根据自己的操作系统进行下载对应的版本,如图所示是 Windows:
然后根据安装程序步骤进行安装即可
4. 在 Git 中启用 LFS
同样打开 Git bash here,初始化 Git LFS 的全局配置(仅需一次),命令如下:
git lfs install
初始化完成如图所示:
5. 追踪大文件
然后使用 lfs track 命令来追踪指定的文件,路径需要与刚刚步骤 1 find 所找到的文件名一致,命令如下:
# file name 是刚刚步骤 1 所找到的文件名
# 路径也需要和 find 命令找到的一致
git lfs track "file name"
例如,刚刚所查询到的文件名路径为"./TWOSIDES/data/9606.protein.links.full.v12.0.txt",则命令如下:
git lfs track "./TWOSIDES/data/9606.protein.links.full.v12.0.txt"
该命令会生成一个名为 .gitattributes 的文件,如图所示:
6. 提交 .gitattributes 文件
首先将 .gitattributes 文件提交到暂存区,命令如下:
git add .gitattributes
然后再将该文件进行提交,命令如下:
# "" 双引号里面的是提交信息,可自行修改
git commit -m "feat: Configure Git LFS for large data file"
7. 重写历史,转换大文件为 LFS 指针
使用 git lfs migrate 命令来扫描整个 Git 历史,找到那个大文件,并将其转换为 LFS 指针,命令如下:
# migrate import 表示将历史记录中的文件导入到 LFS
# --include 指定要转换的文件
# file name 是刚刚步骤 1 所找到的文件名
git lfs migrate import --include="file name"
例如,刚刚所查询到的文件名路径为"./TWOSIDES/data/9606.protein.links.full.v12.0.txt",则命令如下:
git lfs migrate import --include="./TWOSIDES/data/9606.protein.links.full.v12.0.txt"
该命令会遍历 master 分支的所有提交,把那个大文件从 Git 的常规存储中剥离,替换成一个小的文本指针,会花一点时间
注意:该操作会改变之前所有相关的 commit ID
8. 重新进行提交推送
下面就可以通过命令或者 pycharm 对刚刚所需要提交推送的文件重新进行提交推送
① 将修改后的历史推送到远程仓库
由于本地的历史已经被 migrate 命令重写了,它和远程仓库的历史不再一致。因此,必须使用强制推送(force push)推送,命令如下:
git push origin master --force
② 使用 pycharm 进行提交推送
使用 pycharm 进行提交推送可以查看之前的帖子
ps:不管是通过命令还是 pycharm 重新进行推送,刚刚的大文件已经转换成了一个非常小的文本指针文件,该指针文件里记录了实际大文件的存储位置、哈希值等信息
当勾选该文件并提交时,只是把这个小小的指针文件提交到了 Git 的历史记录里,实际的大文件内容会在你 git push 的时候由 LFS 客户端单独上传到 LFS 的服务器上