Git

名称

gitprotocol-capabilities - 协议 v0 和 v1 功能

概要

<over-the-wire-protocol>

说明

注意
本文档描述了包协议版本 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 功能允许服务器在找到一个既可以作为客户端需求和客户端已拥有集合的公共基础,又可以作为提交的提交后,立即返回“ACK obj-id continue”。

通过尽早发送此内容,服务器可以潜在阻止客户端进一步沿着客户端存储库历史记录的特定分支向下移动。客户端可能仍需要向下移动其他分支,为这些分支发送 have 行,直到服务器完全切入 DAG,或者客户端已声明“完成”。

如果没有 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] 中的“包文件协商”部分。

no-done

此功能只能与智能 HTTP 协议一起使用。如果同时存在 multi_ack_detailed 和 no-done,则发送方可以立即在其第一个“ACK obj-id ready”消息后发送一个包。

如果没有智能 HTTP 协议中的 no-done,服务器会话将结束,并且客户端必须进行另一次传输以发送“done”,然后服务器才能发送该包。no-done 去掉了最后一轮,从而略微减少了延迟。

thin-pack

精简包是包含引用包中不存在的基础对象(但接收端已知存在)的增量。这可以显著减少网络流量,但要求接收端知道如何通过将缺少的基础添加到包中来“增厚”这些包。

当上传包服务器可以生成并发送精简包时,它会通告精简包。当客户端了解如何“增厚”精简包时,它会请求精简包功能,通知服务器它可以接收此类包。如果客户端无法将精简包转换成自包含包,则客户端不得请求精简包功能。

另一方面,默认情况下假定接收包能够处理精简包,但可以通过通告无精简功能来要求客户端不使用此功能。如果服务器通告无精简功能,则客户端不得发送精简包。

这种不对称的原因是历史性的。接收包程序在发明精简包之后才出现,因此从历史上看,接收包的参考实现始终理解精简包。稍后添加无精简功能允许接收包以向后兼容的方式禁用此功能。

边带、边带 64k

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

这两个选项互斥。现代客户端始终偏爱边带 64k

任一模式都表示包文件数据将被流式传输,分成最多 1000 字节(对于边带)或 65520 字节(对于边带 64k)的数据包。每个数据包由一个前导的 4 字节 pkt 行长度(表示数据包中的数据量)、一个 1 字节流代码和实际数据组成。

流代码可以是以下之一

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

对于能够处理更大数据包的较新客户端,"边带 64k" 功能作为一种请求几乎完全填满的数据包的方式出现,同时保持对较旧客户端的向后兼容性。

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

客户端必须只发送“边带”和“边带 64k”中的一个。如果客户端同时请求这两个,则服务器必须将其诊断为错误。

ofs 增量

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

代理

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

对象格式

此功能采用哈希算法作为参数,表示服务器支持给定的哈希算法。可以多次发送;如果这样做,则第一个给定的算法将用于引用通告中。

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

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

符号引用

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

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

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

浅克隆

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

自上次加深

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

不加深

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

相对加深

如果客户端请求此功能,“加深”命令的语义将发生改变。“深度”参数是当前浅边界开始的深度,而不是远程引用开始的深度。

no-progress

客户端使用“git clone -q”或类似命令启动,并且不希望使用旁带 2。基本上,客户端只是说“我不希望在旁带上接收流 2,因此不要发送给我,如果你发送了,我无论如何都会将其丢弃”。但是,旁带通道 3 仍然用于错误响应。

include-tag

include-tag 功能是关于在发送指向的对象时发送带注释的标签。如果我们将对象打包到客户端,并且标签对象恰好指向该对象,我们也会打包标签对象。通常,这允许客户端在获取分支时通过单个网络连接获取所有新的带注释的标签。

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

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

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

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

report-status

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

report-status-v2

功能 report-status-v2 通过添加新的“选项”指令来扩展功能 report-status,以便支持由“proc-receive”钩子重写的引用。“proc-receive”钩子可以处理伪引用的命令,该命令可能会创建或更新具有不同名称、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 功能,则它能够接受原子推送。如果推送客户端请求此功能,则服务器将在一个原子事务中更新 ref。所有 ref 都将更新,或者都不更新。

push-options

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

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 服务器愿意接受已签名的 push 证书,并要求将 <nonce> 包含在 push 证书中。除非 receive-pack 服务器宣告此功能,否则 send-pack 客户端不得发送 push-cert 数据包。

filter

如果 upload-pack 服务器宣告了 filter 功能,fetch-pack 可能会发送“filter”命令以请求部分克隆或部分获取,并请求服务器从 packfile 中省略各种对象。

session-id=<session-id>

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

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

GIT

git[1] 套件的一部分

scroll-to-top