Skip to content

传输协议

Git 支持多种网络传输协议,用于在本地仓库和远程仓库之间交换数据。了解传输协议有助于理解 fetch/push 的工作机制。

哑协议(HTTP)

哑协议(Dumb HTTP)是最简单的传输方式,服务器只需要能提供静态文件即可:

客户端通过 HTTP GET 请求直接读取 Git 仓库文件:
GET /repo.git/info/refs
GET /repo.git/objects/ab/cdef...
GET /repo.git/objects/pack/pack-xxx.pack

特点:

  • 只需要普通的 Web 服务器
  • 无需特殊 Git 服务
  • 只读(不支持 push)
  • 效率低(每个对象单独请求)
  • 现代 Git 基本不使用

配置哑协议服务:

bash
# 启用哑协议(在服务端执行)
git update-server-info

# 配置 Web 服务器提供 Git 目录即可

智能协议(Smart HTTP / SSH / Git)

智能协议(Smart Protocol)通过特定的端点进行协商,实现高效的数据传输:

Smart HTTP

bash
# Smart HTTP 的 URL 格式
https://github.com/user/repo.git

# 关键端点:
POST /repo.git/git-upload-pack 用于 fetch
POST /repo.git/git-receive-pack 用于 push

特点:

  • 防火墙友好(443/80 端口)
  • 支持读写操作
  • 需要认证(HTTPS + Token/密码)
  • 现代 Git 主流方式之一

SSH 协议

bash
# SSH 的 URL 格式
git@github.com:user/repo.git
ssh://git@github.com/user/repo.git

# SSH 底层命令
git fetch 通过 SSH 调用远程的 git-upload-pack
git push 通过 SSH 调用远程的 git-receive-pack

特点:

  • 安全加密传输
  • 通过 SSH 密钥认证,无需密码
  • 需要 22 端口(可能被防火墙封锁)
  • 性能良好

Git 协议

bash
# Git 协议的 URL(9418 端口)
git://github.com/user/repo.git

特点:

  • 最快(没有加密和认证开销)
  • 只读
  • 无认证(不安全,不用于私有仓库)
  • GitHub 已于 2022 年禁用

传输过程

Git 的传输分三个阶段:

阶段1:引用发现(Reference Discovery)

客户端询问服务端有哪些引用:

客户端 → 服务端:请求引用列表
服务端 → 客户端:
  sha1 refs/heads/main
  sha1 refs/heads/develop
  sha1 refs/tags/v1.0.0
  0000(结束标志)

阶段2:对象协商(Object Negotiation)

客户端告诉服务端:

  • want:客户端需要的提交(远程有,本地没有)
  • have:客户端已经有的提交(找共同基础)
客户端 → 服务端:
  want abc123(需要这个提交)
  have def456(已经有这个提交)
  done(协商结束)

服务端 → 客户端:
  ack def456(确认共同基础)

阶段3:数据传输(Data Transfer)

服务端生成并发送 pack 文件(只包含客户端没有的对象):

服务端 → 客户端:
  PACK 文件(包含所有 want 的提交及其依赖的对象)

协议版本

协议 v0(默认兼容版本):

  • 服务端主动列出所有引用
  • 在大型仓库中,引用列表可能很大

协议 v2(Git 2.26+,推荐):

  • 客户端先发送能力广告
  • 服务端只发送客户端需要的信息
  • 支持引用过滤,大幅减少数据量
bash
# 使用协议 v2(大多数服务端已支持)
git config --global protocol.version 2

# 验证
GIT_TRACE_PACKET=1 git ls-remote origin 2>&1 | head -20

本地协议

用于同一台机器的仓库之间传输:

bash
# 文件路径协议
git clone /path/to/repo.git
git clone file:///path/to/repo.git

# file:// 与直接路径的区别
# 直接路径:建立硬链接(更快)
# file://:完整的网络传输语义(更慢但更安全)

协议对比

协议端口认证读写速度安全
哑 HTTP80/443只读
Smart HTTP80/443HTTPS读写
SSH22密钥/密码读写
Git9418只读最快
本地文件文件权限读写最快取决于文件系统

调试传输过程

bash
# 查看 pack 数据传输详情
GIT_TRACE_PACKET=1 git fetch 2>&1 | head -50

# 查看传输性能统计
git fetch --verbose

# 查看对象传输量
git fetch 2>&1 | grep -E "objects|KiB|MiB"

总结

协议推荐场景
Smart HTTP(HTTPS)CI/CD、防火墙环境、Windows 开发
SSH日常开发、团队协作
本地文件同机器仓库、备份

在选择传输协议时,SSH 最适合日常开发(密钥认证,安全高效),HTTPS 适合需要穿越严格防火墙或 CI/CD 环境,因为 443 端口基本不会被封锁。