- 调试
-
git push
时的 Broken pipe 错误 -
ssh_exchange_identification
错误 -
git push
/git pull
期间超时 - 错误:传输关闭,仍有未读取的数据
- 针对 LDAP 用户,使用 SSH 执行 Git fetch 时遇到密码过期错误
- Git Fetch 错误: “HTTP Basic: Access Denied”
401
git clone
成功期间记录401
错误- 当执行 HTTP Git 操作时遇到
403
错误
Git 故障排查
有时事情并没有像原本应该的那样工作,或者如你所期望的那样你正在使用 Git。以下是有关 Git 使用的故障排除和解决问题的一些提示。
调试
当对 Git 进行故障排查时,可以尝试以下调试技巧。
为 Git 命令使用自定义 SSH key
GIT_SSH_COMMAND="ssh -i ~/.ssh/gitlabadmin" git <command>
调试克隆问题
通过 SSH 的 Git 操作:
GIT_SSH_COMMAND="ssh -vvv" git clone <git@url>
通过 HTTPS 的 Git 操作:
GIT_TRACE_PACKET=1 GIT_TRACE=2 GIT_CURL_VERBOSE=1 git clone <url>
用追踪调试 Git
Git 包含完整的 Git 命令追踪调试手段,比如:
-
GIT_TRACE_PERFORMANCE=1
:启用性能数据追踪,显示每个git
调用的耗时。 -
GIT_TRACE_SETUP=1
:启用仓库和环境追踪,显示git
发现仓库和环境的详细信息。 -
GIT_TRACE_PACKET=1
:启用网络操作追踪,显示数据包级别的详细信息。 -
GIT_CURL_VERBOSE=1
:启用curl
的详细输出,可能包含凭证信息。
git push
时的 Broken pipe 错误
当您尝试推送到远端仓库时候,可能会遇到 ‘Broken pipe’ 错误。通常您会看到:
Write failed: Broken pipe
fatal: The remote end hung up unexpectedly
要修复此问题,下面是一些可能的解决方案。
增加 Git 中的 POST 缓存大小
当您尝试通过 HTTPS 来将大文件推送到仓库中时,您可能会遇到如下错误:
fatal: pack has bad object at offset XXXXXXXXX: inflate returned -5
要解决此问题:
-
在您的本地 Git 配置中增加 http.postBuffer。默认值是 1MB。比如,如果克隆一个 500MB 的仓库失败,执行以下命令:
- 打开终端或命令行窗口。
-
增加
http.postBuffer
值:# Set the http.postBuffer size in bytes git config http.postBuffer 524288000
如果本地配置无法解决问题,您可能需要修改服务器配置。这时候就需要非常小心了,而且需要确保您能访问服务器。
-
在服务器端增加
http.postBuffer
:- 打开终端或命令行窗口。
-
修改 GitLab 实例的
gitlab.rb
文件:gitaly['configuration'] = { # ... git: { # ... config: [ # Set the http.postBuffer size, in bytes {key: "http.postBuffer", value: "524288000"}, ], }, }
-
应用配置变更:
sudo gitlab-ctl reconfigure
Stream 0 was not closed cleanly
如果您看到此错误,可能是因为您的网络连接速度较慢。
RPC failed; curl 92 HTTP/2 stream 0 was not closed cleanly: INTERNAL_ERROR (err 2)
如果您使用 HTTP 而不是 SSH 来操作 Git,尝试以下修复方法:
- 在 Git 配置中通过
git config http.postBuffer 52428800
增加 POST 缓存大小。 - 使用
git config http.version HTTP/1.1
切换到HTTP/1.1
。
如果上面的方法都无法解决此问题,您可能需要考虑更换网络服务提供商。
检查您的 SSH 配置
如果通过 SSH 推送,首先检查您的 SSH 配置,因为 ‘Broken pipe’ 错误有时是由于 SSH 的底层问题(如认证)引起的。所以需要确保 SSH 配置正确,可遵循SSH 故障排查文件。
如果您是具有服务器访问权限的极狐GitLab 管理员,您还可以通过在客户端或服务器上配置 SSH keep-alive
来防止会话超时。
在客户端配置 SSH:
-
在 UNIX 上,编辑
~/.ssh/config
(如果不存在则创建)并添加或编辑:Host your-gitlab-instance-url.com ServerAliveInterval 60 ServerAliveCountMax 5
-
在 Windows 上,如果使用 PuTTY,打开您的会话属性,然后前往 “链接” 并在 “发送空包以保持会话活跃” 下,设置
Seconds between keepalives (0 to turn off)
为60
。
在服务器端配置 SSH,编辑 /etc/ssh/sshd_config
并添加:
ClientAliveInterval 60
ClientAliveCountMax 5
运行 git repack
If ‘pack-objects’ type errors are also being displayed, you can try to
run a git repack
before attempting to push to the remote repository again:
git repack
git push
升级您的 Git 客户端
如果您的 Git 版本比较老旧(< 2.9),建议升级到 >= 2.9。
ssh_exchange_identification
错误
当尝试通过 SSH 推送或拉取时,用户可能会经历如下问题:
Please make sure you have the correct access rights
and the repository exists.
...
ssh_exchange_identification: read: Connection reset by peer
fatal: Could not read from remote repository.
或
ssh_exchange_identification: Connection closed by remote host
fatal: The remote end hung up unexpectedly
或
kex_exchange_identification: Connection closed by remote host
Connection closed by x.x.x.x port 22
此错误通常预示着 SSH 守护进程的 MaxStartups
是 SSH 链接的瓶颈点。此设置制定了最大并发数,SSH 守护进程的未认证链接数。这会影响具有正确认证凭据的用户,因为刚开始时,每一个链接都是“未认证的”。此值的默认值为 10
。
可以通过检查宿主机的 sshd
日志来验证。对于 Debian 系统,检查 /var/log/auth.log
,对于 RHEL 派生系统,检查 /var/log/secure
。
sshd[17242]: error: beginning MaxStartups throttling
sshd[17242]: drop connection #1 from [CLIENT_IP]:52114 on [CLIENT_IP]:22 past MaxStartups
此错误的出现建议您增加未认证的并发 SSH 连接数。而且预示着深层次的问题可能与网络相关。
增加未认证的并发 SSH 连接数
通过在 /etc/ssh/sshd_config
中添加或修改值来增加极狐GitLab 服务器的 MaxStartups
:
MaxStartups 100:30:200
100:30:200
意味着 100 个 SSH 链接是不受限制且允许的,之后 30% 的链接会掉线,直到达到绝对最大值 200。
修改 MaxStartups
后,检查配置是否有错误:
sudo sshd -t -f /etc/ssh/sshd_config
如果配置运行无误,重启 SSH 守护进程以使更改生效:
# Debian/Ubuntu
sudo systemctl restart ssh
# CentOS/RHEL
sudo service sshd restart
git push
/ git pull
期间超时
如果从仓库拉取/或推送到仓库时超过 50s,就会有超时问题。这会记录操作执行的次数和其对应的时间,诸如:
remote: Running checks for branch: master
remote: Scanning for LFS objects... (153ms)
remote: Calculating new repository size... (cancelled after 729ms)
这可以用来进一步调查哪些操作执行缓慢,并为 GitLab 提供更多信息,以便改进服务。
错误:操作超时
当您在使用 Git 时,如果遇到了如下错误,这通常预示着这是一个网络问题:
ssh: connect to host gitlab.com port 22: Operation timed out
fatal: Could not read from remote repository
要帮助识别深层次问题:
- 通过切换网络(例如,从 Wi-Fi 切换到蜂窝数据)来排除本地网络或防火墙问题。
- 使用
mtr
命令来收集traceroute
和ping
信息:mtr -T -P 22 <gitlab_server>.com
。
错误:传输关闭,仍有未读取的数据
有时候,当克隆旧的或大型仓库时,当通过 HTTP 运行 git clone
时可能会遇到如下错误:
error: RPC failed; curl 18 transfer closed with outstanding read data remaining
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed
此问题是 Git 自身的常见问题,这是因为其没有能力来处理大型文件或大量文件。Git LFS 可以解决这个问题,但它也有一些限制。通常,问题可能由以下原因之一引起:
- 仓库中的文件数量。
- 仓库的历史记录数量。
- 仓库中存在大文件。
如果在您克隆大型仓库时出现此问题,您可以减小克隆深度为 1
。比如:
此方法不能解决深层次的问题,但是您可以成功克隆仓库。要减小克隆深度为 1
,运行:
variables:
GIT_DEPTH: 1
针对 LDAP 用户,使用 SSH 执行 Git fetch 时遇到密码过期错误
如果私有化部署实例的 git fetch
返回了 HTTP 403 Forbidden
错误,可能是因为此用户在极狐GitLab 数据库中的密码过期日期(users.password_expires_at
)设置在过去的日期:
Your password expired. Please access GitLab from a web browser to update your password.
通过 SSO 发起请求而且 password_expires_at
不为空时会返回此错误:
"403 Forbidden - Your password expired. Please access GitLab from a web browser to update your password."
要解决此问题,您可以通过如下方式(其中之一)来更新密码过期:
-
使用极狐GitLab Rails 控制台来检查并更新用户数据:
user = User.find_by_username('<USERNAME>') user.password_expired? user.password_expires_at user.update!(password_expires_at: nil)
-
使用
gitlab-psql
:# gitlab-psql UPDATE users SET password_expires_at = null WHERE username='<USERNAME>';
Git Fetch 错误: “HTTP Basic: Access Denied”
当您通过 HTTP(S) 使用 Git 时,可能会收到 HTTP Basic: Access denied
错误,可参考双因素认证故障排除指南。
401
git clone
成功期间记录 401
错误
当使用 HTTP 克隆仓库时,[]production_json.log
](../../administration/logs/index.md#production_jsonlog) 文件可能会显示初始状态为 401
(未经授权),很快就会显示 200
。
{
"method":"GET",
"path":"/group/project.git/info/refs",
"format":"*/*",
"controller":"Repositories::GitHttpController",
"action":"info_refs",
"status":401,
"time":"2023-04-18T22:55:15.371Z",
"remote_ip":"x.x.x.x",
"ua":"git/2.39.2",
"correlation_id":"01GYB98MBM28T981DJDGAD98WZ",
"duration_s":0.03585
}
{
"method":"GET",
"path":"/group/project.git/info/refs",
"format":"*/*",
"controller":"Repositories::GitHttpController",
"action":"info_refs",
"status":200,
"time":"2023-04-18T22:55:15.714Z",
"remote_ip":"x.x.x.x",
"user_id":1,
"username":"root",
"ua":"git/2.39.2",
"correlation_id":"01GYB98MJ0CA3G9K8WDH7HWMQX",
"duration_s":0.17111
}
由于 HTTP基本认证的工作原理,您应该预料到,每次通过 HTTP 执行 Git 操作时,最初都会有这条状态码为 401
的日志记录。
当 Git 客户端初始化一个克隆时,初始请求不会提供任何认证细节,所以极狐GitLab 返回 401 Unauthorized
。几毫秒后,Git 客户端发送一个包含认证细节的后续请求。这个后续请求应该成功,并导致 200 OK
日志记录。
如果 401
记录没有对应的 200
记录,那么 Git 客户端很可能使用了以下任一情况:
- 不正确的密码。
- 已过期或已撤销的令牌。
如果未纠正,您可能会遇到 403
(Forbidden) 错误。
当执行 HTTP Git 操作时遇到 403
错误
当您通过 HTTP 执行 Git 操作时,403
错误意味着您的 IP 地址已经被认证失败所阻止:
fatal: unable to access 'https://gitlab.com/group/project.git/': The requested URL returned error: 403
403
记录会被发送到 production_json.log
:
{
"method":"GET",
"path":"/group/project.git/info/refs",
"format":"*/*",
"controller":"Repositories::GitHttpController",
"action":"info_refs",
"status":403,
"time":"2023-04-19T22:14:25.894Z",
"remote_ip":"x.x.x.x",
"user_id":1,
"username":"root",
"ua":"git/2.39.2",
"correlation_id":"01GYDSAKAN2SPZPAMJNRWW5H8S",
"duration_s":0.00875
}
如果您的 IP 地址已经被阻止,则会在 auth_json.log
有相对应的记录:
{
"severity":"ERROR",
"time":"2023-04-19T22:14:25.893Z",
"correlation_id":"01GYDSAKAN2SPZPAMJNRWW5H8S",
"message":"Rack_Attack",
"env":"blocklist",
"remote_ip":"x.x.x.x",
"request_method":"GET",
"path":"/group/project.git/info/refs?service=git-upload-pack"}
失败的认证禁止限制差异取决于您使用的是私有化部署实例还是JihuLab.com。