- 调试
-
git push
时的断管错误 -
ssh_exchange_identification
错误 -
git push
/git pull
时超时 - 错误:传输关闭时仍有未读取的数据
- LDAP 用户使用 SSH 进行 Git fetch 时的密码过期错误
- Git fetch 时的错误:“HTTP Basic: Access Denied”
- 成功
git clone
时记录的401
错误 - 通过 HTTP 执行 Git 操作时的
403
错误
有时候,在使用 Git 时,事情并不像你期望的那样运作。以下是一些关于如何排查和解决 Git 问题的建议。
调试
在排查 Git 的问题时,可以尝试以下调试技术。
为 Git 命令使用自定义 SSH 密钥
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
时的断管错误
在尝试推送到远程仓库时,可能会出现“断管”错误。推送时,你通常会看到:
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 值。默认值是 1 MB。例如,如果在克隆 500 MB 仓库时
git clone
失败,请执行以下操作:- 打开终端或命令提示符。
-
增加
http.postBuffer
值:# 设置 http.postBuffer 的大小(字节) git config http.postBuffer 524288000
如果本地配置没有解决问题,你可能需要修改服务器配置。这应该谨慎进行,并且只有在你有服务器访问权限时才进行。
-
在服务器端增加
http.postBuffer
:- 打开终端或命令提示符。
-
修改极狐GitLab 实例的
gitlab.rb
文件:gitaly['configuration'] = { # ... git: { # ... config: [ # 设置 http.postBuffer 的大小(字节) {key: "http.postBuffer", value: "524288000"}, ], }, }
-
应用配置更改:
sudo gitlab-ctl reconfigure
流 0 未被正常关闭
如果你看到这个错误,可能是由于网络连接速度慢:
RPC failed; curl 92 HTTP/2 stream 0 was not closed cleanly: INTERNAL_ERROR (err 2)
如果你使用的是通过 HTTP 的 Git 而不是 SSH,请尝试以下解决方案之一:
- 在 Git 配置中增加 POST 缓冲区大小,使用
git config http.postBuffer 52428800
。 - 使用
git config http.version HTTP/1.1
切换到HTTP/1.1
协议。
如果这两种方法都无法解决错误,你可能需要一个不同的互联网服务提供商。
检查你的 SSH 配置
如果通过 SSH 推送,首先检查你的 SSH 配置,因为“断管”错误有时是由 SSH 的底层问题(如认证)引起的。请确保 SSH 按照SSH 故障排除文档中的说明正确配置。
如果你是具有服务器访问权限的极狐GitLab 管理员,你还可以通过在客户端或服务器上配置 SSH keep-alive
来防止会话超时。
{{< alert type=”note” >}}
无需同时配置客户端和服务器。
{{< /alert >}}
在客户端上配置 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
如果也显示了“pack-objects”类型错误,你可以在再次尝试推送到远程仓库之前运行 git repack
:
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 守护进程的最大并发未认证连接数。这影响了拥有正确认证凭据(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
时超时
如果从你的仓库拉取/推送超过 50 秒,则会发出超时。它包含已执行操作的数量和各自的时间日志,如下例所示:
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 切换到蜂窝数据)以排除本地网络或防火墙问题。
- 运行此 bash 命令以收集
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
在极狐GitLab 私有化部署上返回此 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
不是 null
时会返回此错误:
"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
错误,请参考双因素认证故障排除指南。
成功 git clone
时记录的 401
错误
使用 HTTP 克隆仓库时,production_json.log
文件可能会显示初始状态为 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 执行的 Git 操作,你都应该预期到这个初始 401
日志条目,这是由于 HTTP 基本认证的工作原理。
当 Git 客户端启动克隆时,发送给极狐GitLab 的初始请求不提供任何认证详细信息。极狐GitLab 会为该请求返回一个 401 Unauthorized
结果。几毫秒后,Git 客户端发送一个包含认证详细信息的后续请求。此第二个请求应成功,并导致 200 OK
日志条目。
如果 401
日志条目缺少相应的 200
日志条目,则 Git 客户端可能使用了:
- 错误的密码。
- 过期或已撤销的令牌。
如果不纠正,你可能会遇到403
(禁止)错误。
通过 HTTP 执行 Git 操作时的 403
错误
通过 HTTP 执行 Git 操作时,403
(禁止)错误表示你的 IP 地址已被失败认证禁用:
fatal: unable to access 'https://gitlab.com/group/project.git/': The requested URL returned error: 403
在 production_json.log
中可以看到 403
:
{
"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"}
失败认证禁用限制因你使用的是极狐GitLab 私有化部署还是极狐GitLab SaaS而异。