Appearance
传输协议
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://:完整的网络传输语义(更慢但更安全)协议对比
| 协议 | 端口 | 认证 | 读写 | 速度 | 安全 |
|---|---|---|---|---|---|
| 哑 HTTP | 80/443 | 无 | 只读 | 慢 | 低 |
| Smart HTTP | 80/443 | HTTPS | 读写 | 快 | 高 |
| SSH | 22 | 密钥/密码 | 读写 | 快 | 高 |
| Git | 9418 | 无 | 只读 | 最快 | 低 |
| 本地文件 | — | 文件权限 | 读写 | 最快 | 取决于文件系统 |
调试传输过程
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 端口基本不会被封锁。