0. 问题背景
最近因为工作需要,在一台新电脑(windowsPC, WSL)上搭建开发环境的时候,遇到了一个 git 错误。因为这些年都是在使用 IDE 集成的 git 操作来做控制版本,导致有相当一段时间没有使用 git 命令行操作,难免有些生疏,这次遇到的问题并不难,但还是有必要记录一下,巩固基础,供自己和大家学习参考。
1. 问题分析
问题是在使用 git clone 命令从远端代码仓库拷贝项目到本地的时候报错的。如下所示:
git clone https://github.com/XXX/MyGitPractice.git
Cloning into 'MyGitPractice'...
remote: Enumerating objects: 23, done.
remote: Counting objects: 100% (23/23), done.
remote: Compressing objects: 100% (10/10), done.
error: RPC failed; curl 18 transfer closed with outstanding read data remaining
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: unpack-objects failed
众所周知,git clone 有两种方式: HTTP 或 SSH 连接远程机器。
我这里使用的是 HTTP 方式,因为它相比 SSH 而言,更简单、更常用一些(起码不需要用户名)。这个方式通常情况下都没什么问题,但是有些特殊情况就会踩坑,比如刚好就是我这次遇到的问题。我们根据命令行的操作返回结果(报错信息)来逐行分析:
- 前 3 行的信息都来自远程机器的提示,可以看到都是顺利完成的。
- 第 4 行是 error 信息,提示是由 RPC failed 引起的,传输关闭了,但是还有没读完的数据。
- 最后 3 行是 fatal 信息,远程机器意外挂起 + EOF + 解包对象失败。
所以,分析问题从第 4 行开始。其中,RPC 是远程过程调用(Remote Procedure Call),失败的原因 —— 要么是连接的时候有问题,要么就是连接以后传输数据的时候有问题。
这里初步判断是属于后者,因为提示信息有提到 “with outstanding read data remaining(还有没读完的数据)”。网上搜索查询了一下,发现很多人说这个错误的原因是要拷贝的数据量太大,导致 http 的 buffer 溢出,崩溃了。那么对应的 解决方法分为三类:
[ 方法一 ]:增加 Git 的 HTTP 缓冲区大小。设置 http.postBuffer
的值。
git config --global http.postBuffer 524288000
[ 方法二 ]:化整为零,分成多次来操作,使得每次要拷贝数据的大小变小一些。
这个方法不可行,因为要克隆的项目本身就是一个整体,而且分开多次操作也比较麻烦。
[ 方法三 ]:更换远程连接方式,使用 SSH。
这就属于直接“更换赛道”,跳出当前问题场景,尝试在新场景下达成最终目标了。
2. 问题解决
根据上面的分析,我们需要选择一个方法来解决问题。
首先,[ 方法二 ]太麻烦直接 pass 掉。
其次,[ 方法一 ]通过更改 buffer 值又有局限性(即不能确定到底多大的buffer值是合适的,因为不同的代码仓库的数据大小各有不同)。
所以,最终选择了[ 方法三 ],使用 SSH。毕竟这种数据量太大的情况(尤其是单个文件大小比较大的)并不常见。
具体操作:
- Step0:准备新设备(环境)的 SSH key
如果没安装 ssh-server 的话,需要先安装一下(如果已安装则直接跳过):
sudo apt install openssh-server
然后生成 (一般都是 rsa 类型)ssh key ,(如果已生成过 key 则直接跳过):
ssh-keygen -t rsa
密钥文件生成在 $HOME/.ssh下这个隐藏目录下,默认的文件名是 “id_rsa.pub”。可以直接使用cat 命令查看并复制 ssh-key 公钥内容:
- Step1: 添加 ssh-key 公钥到 github
在GitHub的个人账号中,找到 “SSH and GPG keys” 选项,按照提示添加 ssh key。如图所示,这个是添加了以后的截图:
在本地环境可以用如下命令来验证是否成功生效,运行命令以后会提示 “本地与远程机器的认证还没建立,是否需要继续连接”,选择 “yes” 以后,就会出现认证成功的欢迎信息。结果如图所示:
- Step2: 使用SSH 方式 重新运行 git clone 命令:
至此,我们可以看到远程代码仓库已经成功的复制到本地了。
3. 问题总结
基础很重要,命令行的使用必不可少。
遇到问题,分析问题,最后选择适合自己的方法解决来问题最重要。