传输协议

大约 2 分钟

Git 可以通过两种主要的方式在版本库之间传输数据:“哑(dumb)” 协议和 “智能(smart)” 协议。

# 哑协议

哑协议是一个基于 HTTP 协议的只读版本库,已经很少用到了。

在传输过程中,服务端不需要有针对 Git 特有的代码;抓取过程是一系列 HTTP 的 GET 请求,这种情况下,客户端可以推断出服务端 Git 仓库的布局。所以使用哑协议的版本库很难保证安全性和私有化,所以现在基本很少使用到了。

“哑协议”的只读限制是因为其服务端没有一个 Git 的守护进程在持续的关注“客户端”的所需并与之关注,所以只能“客户端”去发起请求获取远程的变更。

# 智能协议

智能协议支持读写模式,效率比哑协议高,是目前最常用的传输方式。

但它需要在服务端运行一个进程,它可以读取本地数据,理解客户端有什么和需要什么,并为它生成合适的包文件。 总共有两组进程用于传输数据,它们分别负责上传和下载数据。

# 上传数据

为了上传数据至远端,Git 使用 send-packreceive-pack 进程。运行在客户端上的 send-pack 进程连接到远端运行的 receive-pack 进程。

比如在我们执行 git push origin master 的时候:

  1. Git 会执行 send-pack 进程连接服务器,git-receive-pack 命令会立即为它所拥有的每一个引用发送一行响应。
  2. 你的 send-pack 进程会判断哪些提交记录是它所拥有但服务端没有的。send-pack 会告知 receive-pack 这次推送将会更新的各个引用。服务端在收到请求后相应地作出成功或失败的 HTTP 响应。

# 下载数据

当你在下载数据时,fetch-packupload-pack 进程就起作用了。客户端启动 fetch-pack 进程,连接至远端的 upload-pack 进程,以协商后续传输的数据。

  1. fetch-pack 连接远程服务器,然后 upload-pack 会返回类似 receive-pack 返回的内容。
  2. fetch-pack 进程查看它自己所拥有的对象,并响应 “want” 和它需要的对象的 SHA-1 值。它还会发送 “have” 和所有它已拥有的对象的 SHA-1 值。在列表的最后,它还会发送 “done” 以通知 upload-pack 进程可以开始发送它所需对象的包文件。
上次编辑于: 2024年5月11日 01:53