简体中文 ▾ 主题 ▾ 最新版本 ▾ gitprotocol-capabilities 上次更新于 2.44.0

名称

gitprotocol-capabilities - 协议 v0 和 v1 功能

概要

<over-the-wire-protocol>

描述

注意
本文档描述了 pack 协议版本 0 和 1 的功能。对于版本 2,请参考 gitprotocol-v2[5] 文档。

服务器应该支持本文档中定义的所有功能。

在 receive-pack 和 upload-pack 的初始服务器响应的第一行,第一个引用之后是一个 NUL 字节,然后是一个空格分隔的服务器功能列表。这些允许服务器声明它可以支持和不能支持的内容。

然后客户端将发送一个空格分隔的功能列表,这些功能将生效。客户端不得要求服务器未声明支持的功能。

如果发送了服务器不理解的功能,服务器必须诊断并中止。服务器不得忽略客户端请求且服务器声明的功能。由于这些规则,服务器不得声明其不理解的功能。

atomicreport-statusreport-status-v2delete-refsquietpush-cert 功能由 receive-pack(推送到服务器)进程发送和识别。

ofs-deltaside-band-64k 功能由 upload-pack 和 receive-pack 协议发送和识别。agentsession-id 功能可以选择在两种协议中发送。

所有其他功能仅由 upload-pack(从服务器获取)进程识别。

multi_ack

multi_ack 功能允许服务器在找到一个它可以作为客户端的 wants 和客户端的 have 集之间的公共基础的提交时,立即返回“ACK obj-id continue”。

通过尽早发送此消息,服务器可能会阻止客户端进一步向下遍历客户端存储库历史记录的特定分支。客户端可能仍然需要遍历其他分支,发送这些分支的 have 行,直到服务器拥有 DAG 的完整切入点,或者客户端已说“done”。

如果没有 multi_ack,客户端将以 --date-order 发送 have 行,直到服务器找到一个公共基础。这意味着客户端将发送服务器已知为公共的 have 行,因为它们在时间上与服务器尚未找到公共基础的另一个分支重叠。

例如,假设客户端具有服务器没有的大写提交,并且服务器具有客户端没有的小写提交,如下所示

      +---- u ---------------------- x
     /              +----- y
    /              /
   a -- b -- c -- d -- E -- F
      \
+--- Q -- R -- S

如果客户端想要 x,y 并首先说 have F,S,服务器不知道 F,S 是什么。最终客户端说“have d”,服务器发送“ACK d continue”以让客户端知道停止沿着该行行走(因此不要发送 c-b-a),但尚未完成,它需要 x 的基础。客户端继续使用 S-R-Q,直到到达 a,此时服务器有一个明确的基础,一切都结束了。

如果没有 multi_ack,客户端无论如何都会发送 c-b-a 链,与 S-R-Q 交错。

multi_ack_detailed

这是 multi_ack 的一个扩展,允许客户端更好地理解服务器的内存状态。有关更多信息,请参阅 gitprotocol-pack[5] 的“Packfile 协商”部分。

no-done

此功能应仅与智能 HTTP 协议一起使用。如果 multi_ack_detailed 和 no-done 都存在,则发送者可以自由地在第一个“ACK obj-id ready”消息之后立即发送一个 pack。

如果没有智能 HTTP 协议中的 no-done,服务器会话将结束,客户端必须再次发送“done”才能让服务器发送 pack。 no-done 删除了最后一轮,从而略微减少了延迟。

thin-pack

一个瘦包是指增量引用包中未包含的基础对象(但已知存在于接收端)的包。这可以显着减少网络流量,但它要求接收端知道如何通过将丢失的基础添加到包中来“加厚”这些包。

upload-pack 服务器在它可以生成并发送瘦包时声明 thin-pack。当客户端理解如何“加厚”它时,它会请求 thin-pack 功能,通知服务器它可以接收这样的包。如果客户端无法将瘦包转换为自包含包,则不得请求 thin-pack 功能。

另一方面,默认情况下假定 Receive-pack 能够处理瘦包,但可以通过声明 no-thin 功能来要求客户端不要使用该功能。如果服务器声明了 no-thin 功能,客户端不得发送瘦包。

这种不对称的原因是历史性的。 receive-pack 程序直到瘦包发明后才存在,因此从历史上看,receive-pack 的参考实现始终理解瘦包。稍后添加 no-thin 允许 receive-pack 以向后兼容的方式禁用该功能。

side-band, side-band-64k

此功能意味着服务器可以发送,并且客户端可以理解与 packfile 本身交错的多路复用进度报告和错误信息。

这两个选项是互斥的。 现代客户端始终偏爱 side-band-64k

任一模式都表明 packfile 数据将被流式传输,分解为最多 1000 字节(对于 side_band)或 65520 字节(对于 side_band_64k)的数据包。 每个数据包由一个前导 4 字节 pkt-line 长度(指示数据包中有多少数据)、一个 1 字节流代码和实际数据组成。

流代码可以是以下之一

1 - pack data
2 - progress messages
3 - fatal error message just before stream aborts

“side-band-64k”功能的出现是为了让可以处理更大数据包的新客户端请求实际上几乎完全塞满的数据包,同时保持旧客户端的向后兼容性。

此外,对于 side-band 及其最多 1000 字节的消息,实际上是 999 字节的有效负载和 1 字节的流代码。 对于 side-band-64k,同样如此,您最多有 65519 字节的数据和 1 字节的流代码。

客户端必须只发送“side-band”和“side-band-64k”之一。 如果客户端同时请求两者,服务器必须将其诊断为错误。

ofs-delta

服务器可以发送,并且客户端可以理解 PACKv2,其中 delta 通过包中的位置而不是通过 obj-id 引用其基础。 也就是说,它们可以在 packfile 中发送/读取 OBJ_OFS_DELTA(也称为类型 6)。

agent

服务器可以选择发送 agent=X 形式的功能,以通知客户端服务器正在运行版本 X。 客户端可以选择通过响应 agent=Y 功能来返回自己的代理字符串(但如果服务器没有提及代理功能,则不得这样做)。 XY 字符串可以包含任何可打印的 ASCII 字符,除了空格(即,字节范围 32 < x < 127),并且通常采用“package/version”的形式(例如,“git/1.8.3.1”)。 代理字符串仅用于统计和调试目的,不得用于以编程方式假定是否存在特定功能。

object-format

此功能使用哈希算法作为参数,表示服务器支持给定的哈希算法。 它可以多次发送; 如果是这样,则给定的第一个将用于 ref 声明。

当由客户端提供时,这表示它打算使用给定的哈希算法进行通信。 提供的算法必须是服务器支持的算法。

如果未提供此功能,则假定唯一支持的算法是 SHA-1。

symref

此参数化功能用于通知接收者哪个符号引用指向哪个引用; 例如,“symref=HEAD:refs/heads/master”告诉接收者 HEAD 指向 master。 可以重复此功能以表示多个符号引用。

如果 HEAD 符号引用是正在发送的引用之一,则服务器应该包含此功能。

客户端可以使用此功能的参数在克隆存储库时选择正确的初始分支。

shallow

此功能将“deepen”、“shallow”和“unshallow”命令添加到 fetch-pack/upload-pack 协议,以便客户端可以请求浅克隆。

deepen-since

此功能将“deepen-since”命令添加到 fetch-pack/upload-pack 协议,以便客户端可以请求在特定时间切割的浅克隆,而不是深度。 在内部,它相当于在服务器端执行“rev-list --max-age=<timestamp>”。 “deepen-since”不能与“deepen”一起使用。

deepen-not

此功能将“deepen-not”命令添加到 fetch-pack/upload-pack 协议,以便客户端可以请求在特定修订版本切割的浅克隆,而不是深度。 在内部,它相当于在服务器端执行“rev-list --not <rev>”。 “deepen-not”不能与“deepen”一起使用,但可以与“deepen-since”一起使用。

deepen-relative

如果客户端请求此功能,"deepen" 命令的语义将发生改变。"depth" 参数表示从当前 shallow 边界开始的深度,而不是从远程引用开始的深度。

no-progress

客户端启动时使用了 "git clone -q" 或类似命令,并且不希望接收 side band 2。基本上,客户端只是声明 "我不希望在 sideband 上接收 stream 2,所以不要发送给我,即使你发送了,我也会丢弃它"。但是,sideband 通道 3 仍然用于错误响应。

include-tag

include-tag 功能是指,如果我们发送对象所指向的对象,则发送带注释的标签。 如果我们将一个对象打包给客户端,并且一个标签对象完全指向该对象,我们也会打包该标签对象。 通常,这允许客户端在单个网络连接中获取所有新的带注释的标签(annotated tags)。

当服务器声明此功能时,客户端可以始终发送 include-tag,将其硬编码到请求中。 客户端是否请求 include-tag 仅与客户端对标签数据的需求有关,而与服务器是否已在 refs/tags/* 命名空间中声明对象无关。

如果标签的引用对象已打包,并且客户端已请求 include-tags,则服务器必须打包标签。

客户端必须为服务器忽略 include-tag 并且实际上未在包中发送标签的情况做好准备。 在这种情况下,客户端应发出后续的 fetch 请求以获取 include-tag 本可以提供的标签。

如果服务器支持 include-tag,则无论是否有可用的标签,服务器都应发送 include-tag。

report-status

receive-pack 进程可以接收 report-status 功能,该功能告诉它客户端希望在包文件上传和引用更新后获得报告。 如果推送客户端请求此功能,则在解包和更新引用后,服务器将响应包文件是否成功解包,以及每个引用是否成功更新。 如果其中任何一个不成功,它将发回一条错误消息。 请参阅 gitprotocol-pack[5] 查看示例消息。

report-status-v2

功能 report-status-v2 通过添加新的 "option" 指令来扩展功能 report-status,以便支持 "proc-receive" hook 重写的引用。 "proc-receive" hook 可能会处理伪引用的命令,该命令可能会创建或更新具有不同名称、new-oid 和 old-oid 的引用。 而功能 report-status 无法报告这种情况。 有关详细信息,请参阅 gitprotocol-pack[5]

delete-refs

如果服务器发回 delete-refs 功能,则表示它能够接受零 ID 值作为引用更新的目标值。 它不是由客户端发回的,它只是通知客户端可以发送零 ID 值来删除引用。

quiet

如果 receive-pack 服务器声明了 quiet 功能,则它可以静默人类可读的进度输出,否则在处理接收到的包时可能会显示该输出。 如果本地进度报告也被抑制(例如,通过 push -q,或者如果 stderr 没有指向 tty),send-pack 客户端应响应 quiet 功能以抑制服务器端进度报告。

atomic

如果服务器发送 atomic 功能,则它可以接受原子推送。 如果推送客户端请求此功能,服务器将在一个原子事务中更新引用。 要么所有引用都更新,要么都不更新。

push-options

如果服务器发送 push-options 功能,则它能够在发送更新命令之后但在流式传输包文件之前接受推送选项。 如果推送客户端请求此功能,服务器会将选项传递给处理此推送请求的 pre- 和 post- receive hook。

allow-tip-sha1-in-want

如果 upload-pack 服务器声明了此功能,fetch-pack 可以发送带有对象名称的 "want" 行,这些对象名称存在于服务器上,但未由 upload-pack 声明。 出于历史原因,此功能的名称包含 "sha1"。 对象名称始终使用通过 object-format 功能协商的对象格式给出。

allow-reachable-sha1-in-want

如果 upload-pack 服务器声明了此功能,fetch-pack 可以发送带有对象名称的 "want" 行,这些对象名称存在于服务器上,但未由 upload-pack 声明。 出于历史原因,此功能的名称包含 "sha1"。 对象名称始终使用通过 object-format 功能协商的对象格式给出。

push-cert=<nonce>

声明此功能的 receive-pack 服务器愿意接受签名的推送证书,并要求将 <nonce> 包含在推送证书中。 除非 receive-pack 服务器声明了此功能,否则 send-pack 客户端不得发送 push-cert 数据包。

filter

如果 upload-pack 服务器声明了 filter 功能,fetch-pack 可以发送 "filter" 命令来请求部分克隆或部分获取,并请求服务器从包文件中省略各种对象。

session-id=<session-id>

服务器可以声明一个会话 ID,该会话 ID 可用于在多个请求中识别此进程。 客户端也可以将其自己的会话 ID 声明回服务器。

会话 ID 应该对给定的进程是唯一的。 它们必须适合 packet-line,并且不得包含不可打印或空白字符。 当前的实现使用 trace2 会话 ID(有关详细信息,请参见 api-trace2),但这可能会改变,会话 ID 的用户不应依赖于此事实。

GIT

属于 git[1] 套件的一部分

scroll-to-top