Ubuntu下 Git 克隆gnutls_handshake() failed的问题

本文讲述了在Ubuntu环境下遇到的git克隆错误,解决方法是通过替换gnutls为openssl,提供了详细的步骤,包括卸载原有git、下载git源码、配置依赖并重新构建。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在Ubuntu下git克隆的时候提示gnutls_handshake() failed,搜了一下解决方法有两种:

  1. 使用ssh证书克隆而不是通过https链接进行克隆,但是这样子模块在更新的时候还是会走https,所以有子模块的仓库不适用这个方法。(尝试修改.gitsubmodule文件的子模块链接为git@github.com:xxxxxx仍然访问不正常,如果有成功的欢迎在下方留言。)
git clone git@github.com:xxxx/xxxxx.git
  1. 问题出在 gnutls 模块,解决方案是从源码重新构建 git 安装包,将 gnutls 替换为 openssl 。github上有一个脚本(paul-nelson-baker/git-openssl-shellscript)可以完成这个操作。在gitee上也有同步脚本
#建议先卸载自带的git,否则每次apt upgrade就会把自带的git又装回来
sudo apt remove git

完整脚本:

#!/usr/bin/env bash
set -e

# Gather command line options
for i in "$@"; do 
  case $i in 
    -skiptests|--skip-tests) # Skip tests portion of the build
    SKIPTESTS=YES
    shift
    ;;
    -d=*|--build-dir=*) # Specify the directory to use for the build
    BUILDDIR="${i#*=}"
    shift
    ;;
    -skipinstall|--skip-install) # Skip dpkg install
    SKIPINSTALL=YES
    ;;
    *)
    #TODO Maybe define a help section?
    ;;
  esac
done

# Use the specified build directory, or create a unique temporary directory
BUILDDIR=${BUILDDIR:-$(mktemp -d)}
echo "BUILD DIRECTORY USED: ${BUILDDIR}" 
mkdir -p "${BUILDDIR}"
cd "${BUILDDIR}"

# Download the source tarball from GitHub
sudo apt update
sudo apt install curl -y
sudo apt-get install unzip
git_tarball_url="https://gitee.com$(curl -s -k https://gitee.com/mirrors/git/tags|grep -o 'href="/mirrors/git/repository/archive/.*"'|head -n1 |awk -F '"' '{print $2}' | tr -d '\n')"
echo "DOWNLOADING FROM: ${git_tarball_url}"
curl -s -k -L --retry 5 "${git_tarball_url}" --output "git-source.zip"
unzip -d "${BUILDDIR}" git-source.zip
cd "${BUILDDIR}/git"
# Source dependencies
# Don't use gnutls, this is the problem package.
sudo apt remove --purge libcurl4-gnutls-dev -y || true
# Using apt-get for these commands, they're not supported with the apt alias on 14.04 (but they may be on later systems)
sudo apt-get autoremove -y
sudo apt-get autoclean
# Meta-things for building on the end-user's machine
sudo apt install build-essential autoconf dh-autoreconf -y
# Things for the git itself
sudo apt install libcurl4-openssl-dev tcl-dev gettext asciidoc -y
sudo apt install libexpat1-dev libz-dev -y

# Build it!
make configure
# --prefix=/usr
#    Set the prefix based on this decision tree: https://i.stack.imgur.com/BlpRb.png
#    Not OS related, is software, not from package manager, has dependencies, and built from source => /usr
# --with-openssl
#    Running ripgrep on configure shows that --with-openssl is set by default. Since this could change in the
#    future we do it explicitly
./configure --prefix=/usr --with-openssl
make 
if [[ "${SKIPTESTS}" != "YES" ]]; then
  make test
fi

# Install
if [[ "${SKIPINSTALL}" != "YES" ]]; then
  # If you have an apt managed version of git, remove it
  if sudo apt remove --purge git -y; then
    sudo apt-get autoremove -y
    sudo apt-get autoclean
  fi
  # Install the version we just built
  sudo make install #install-doc install-html install-info
  echo "Make sure to refresh your shell!"
  bash -c 'echo "$(which git) ($(git --version))"'
fi
### 解决方案 当遇到 `gnutls_handshake()` 出现的 `Error in the pull function` 时,通常是因为网络连接问题或者 SSL/TLS 配置不兼容引起的。以下是几种可能的解决方案: #### 方法一:禁用 HTTPS 的 SSL 验证 可以通过设置 Git 不验证 SSL 来绕过此错误。这种方法适用于临时解决问题的情况。 ```bash git config --global http.sslVerify false ``` 需要注意的是,关闭 SSL 验证可能会带来安全风险,因此仅建议在受信任的环境中使用[^1]。 #### 方法二:切换到 HTTP 协议 如果 HTTPS 连接存在问题,可以尝试将远程仓库地址从 HTTPS 切换为 HTTP(如果有提供)。例如: ```bash git remote set-url origin http://github.com/username/repository.git ``` 这种方式避免了 TLS 握手过程中的潜在问题[^2]。 #### 方法三:更新或替换加密库 有时该问题是由于 GnuTLS 库版本较旧或存在 bug 导致的。可以考虑升级 GnuTLS 或者让 Git 使用 OpenSSL 替代 GnuTLS。具体操作如下: - **安装或启用 OpenSSL 支持** 如果操作系统支持 OpenSSL,则可以让 Git 使用它来替代 GnuTLS。例如,在某些 Linux 发行版中,Git 可能默认使用 GnuTLS;通过重新编译或更换包管理器中的依赖项可以选择 OpenSSL。 - **强制指定协议栈** 对于 Windows 用户,可以直接下载最新版本的 Git 客户端并确保其配置文件启用了最新的 TLS 版本。运行以下命令以确认当前使用的 TLS 设置: ```bash git -c http.postBuffer=524288000 clone https://github.com/username/repo.git ``` #### 方法四:调整代理设置 即使已经尝试重置代理,仍需进一步检查是否存在隐式的代理干扰通信链路。执行以下指令清除所有已定义的代理变量: ```bash git config --global --unset http.proxy git config --global --unset https.proxy ``` 随后再次测试克隆功能是否恢复正常。 --- ### 总结 上述四种方式分别针对不同层面的原因提供了修复途径——从简单的全局参数修改到深入探讨底层依赖关系及其相互作用机制。实际应用过程中可根据具体情况逐一排查直至找到最合适的解决办法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值