设置和配置
获取和创建项目
基本快照
分支与合并
共享和更新项目
检查和比较
打补丁
调试
电子邮件
外部系统
服务器管理
指南
管理
底层命令
- 2.44.1 → 2.50.1 无更改
-
2.44.0
2024-02-23
- 2.43.1 → 2.43.7 无更改
-
2.43.0
2023-11-20
- 2.38.1 → 2.42.4 无更改
-
2.38.0
2022-10-02
描述
注意
|
本文档描述了 Pack 协议版本 0 和 1 的功能。对于版本 2,请参阅 gitprotocol-v2[5] 文档。 |
服务器应该(SHOULD)支持本文档中定义的所有功能。
在 receive-pack 和 upload-pack 的初始服务器响应的第一行,第一个引用之后是一个空字节(NUL byte),然后是一个以空格分隔的服务器功能列表。这些功能允许服务器向客户端声明它能或不能支持什么。
客户端随后将发送一个以空格分隔的功能列表,以表明其希望生效的功能。客户端绝不能(MUST NOT)请求服务器未声明支持的功能。
如果客户端发送了服务器不理解的功能,服务器必须(MUST)诊断并中止。服务器绝不能(MUST NOT)忽略客户端请求且服务器已声明的功能。根据这些规则,服务器绝不能(MUST NOT)声明它不理解的功能。
atomic、report-status、report-status-v2、delete-refs、quiet 和 push-cert 功能由 receive-pack(推送到服务器)进程发送和识别。
ofs-delta 和 side-band-64k 功能由 upload-pack 和 receive-pack 协议发送和识别。agent 和 session-id 功能可在两种协议中选择性地发送。
所有其他功能仅由 upload-pack(从服务器获取)进程识别。
multi_ack
multi_ack 功能允许服务器在找到一个可用作客户端的 want 集合和 have 集合之间公共基础的提交时,立即返回“ACK 对象 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 Negotiation”部分。
no-done
此功能仅应与智能 HTTP 协议一起使用。如果 multi_ack_detailed 和 no-done 都存在,则发送方可以在其第一个“ACK 对象 ID ready”消息之后立即发送一个包。
在智能 HTTP 协议中,如果没有 no-done,服务器会话将结束,客户端必须再进行一次往返才能发送“done”,然后服务器才能发送包。no-done 消除了最后一次往返,从而略微减少了延迟。
thin-pack
瘦包(thin pack)是指包含引用包中未包含(但已知存在于接收端)基础对象的增量数据的包。这可以显著减少网络流量,但它要求接收端知道如何通过将缺失的基础添加到包中来“加厚”这些包。
当 upload-pack 服务器能够生成和发送瘦包时,它会声明 thin-pack 功能。客户端在理解如何“加厚”瘦包时请求 thin-pack 功能,从而通知服务器它可以接收此类包。如果客户端无法将瘦包转换为自包含包,则绝不能(MUST NOT)请求 thin-pack 功能。
另一方面,receive-pack 默认假定能够处理瘦包,但可以通过声明 no-thin 功能来要求客户端不要使用该功能。如果服务器声明 no-thin 功能,客户端绝不能(MUST NOT)发送瘦包。
这种不对称的原因是历史性的。receive-pack 程序直到瘦包发明后才出现,因此从历史上看,receive-pack 的参考实现始终理解瘦包。后来添加 no-thin 允许 receive-pack 以向后兼容的方式禁用该功能。
side-band, side-band-64k
此功能意味着服务器可以发送,并且客户端可以理解,与包文件本身交错的多路复用进度报告和错误信息。
这两个选项是互斥的。现代客户端总是倾向于使用 side-band-64k。
两种模式都表明包文件数据将被分割成数据包流式传输,在 side_band 的情况下,每个数据包最多 1000 字节,在 side_band_64k 的情况下,每个数据包最多 65520 字节。每个数据包由一个前导的 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 字节的流代码。
客户端必须(MUST)只发送“side-band”和“side-band-64k”中的一个。如果客户端同时请求两者,服务器必须(MUST)将其诊断为错误。
ofs-delta
服务器可以发送,并且客户端可以理解 PACKv2,其中增量通过其在包中的位置而不是通过对象 ID 来引用其基础。也就是说,它们可以在包文件中发送/读取 OBJ_OFS_DELTA(即类型 6)。
agent
服务器可以选择性地发送形式为 agent=X
的功能,以通知客户端服务器正在运行版本 X
。客户端可以选择性地通过响应 agent=Y
功能来返回自己的代理字符串(但如果服务器未提及 agent 功能,则绝不能(MUST NOT)这样做)。X
和 Y
字符串可以包含除空格之外的任何可打印 ASCII 字符(即,字节范围 32 < x < 127),通常形式为“package/version”(例如,“git/1.8.3.1”)。代理字符串纯粹用于统计和调试目的,绝不能(MUST NOT)用于程序性地假定特定功能的存在或缺失。
object-format
此功能以哈希算法作为参数,表示服务器支持给定的哈希算法。它可以发送多次;如果是这样,第一个给定的哈希算法将用于引用公告中。
当客户端提供时,这表示它打算使用给定的哈希算法进行通信。提供的算法必须是服务器支持的算法。
如果未提供此功能,则假定唯一支持的算法是 SHA-1。
symref
此参数化功能用于告知接收方哪个符号引用指向哪个引用;例如,“symref=HEAD:refs/heads/master”告诉接收方 HEAD 指向 master。此功能可以重复以表示多个符号引用。
如果 HEAD 符号引用是正在发送的引用之一,服务器应该(SHOULD)包含此功能。
客户端可以(MAY)使用此功能中的参数在克隆存储库时选择适当的初始分支。
deepen-since
此功能向 fetch-pack/upload-pack 协议添加了“deepen-since”命令,以便客户端可以请求在特定时间而不是在特定深度截断的浅克隆。在内部,它等同于在服务器端执行“rev-list --max-age=<timestamp>”。“deepen-since”不能与“deepen”一起使用。
deepen-not
此功能向 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 功能涉及在发送对象时发送注释标签,如果这些标签指向该对象。如果我们将一个对象打包给客户端,并且一个标签对象恰好指向该对象,我们也会打包该标签对象。通常,这允许客户端在获取分支时,通过单个网络连接获取所有新的注释标签。
客户端可以(MAY)始终发送 include-tag,在服务器声明此功能时将其硬编码到请求中。客户端是否请求 include-tag 的决定仅与客户端对标签数据的需求有关,而与服务器是否已在 refs/tags/* 命名空间中声明对象无关。
如果标签所引用的对象已被打包且客户端已请求 include-tags,服务器必须(MUST)打包这些标签。
客户端必须(MUST)为服务器忽略 include-tag 且未实际在包中发送标签的情况做好准备。在这种情况下,客户端应该(SHOULD)发出后续的获取操作以获取 include-tag 本应提供给客户端的标签。
如果服务器支持 include-tag,它应该(SHOULD)发送此功能,无论是否有可用标签。
report-status
receive-pack 进程可以接收 report-status 功能,该功能告知它客户端需要一个在包文件上传和引用更新后发生情况的报告。如果推送客户端请求此功能,服务器在解包和更新引用后将响应包文件是否成功解包以及每个引用是否成功更新。如果其中任何一个不成功,它将返回错误消息。有关示例消息,请参阅 gitprotocol-pack[5]。
report-status-v2
report-status-v2 功能通过添加新的“option”指令扩展了 report-status 功能,以支持“proc-receive”钩子重写的引用。“proc-receive”钩子可以处理伪引用的命令,这可能会创建或更新一个具有不同名称、新对象 ID 和旧对象 ID 的引用。而 report-status 功能无法报告此类情况。有关详细信息,请参阅 gitprotocol-pack[5]。
quiet
如果 receive-pack 服务器声明 quiet 功能,则它能够抑制在处理接收到的包时可能显示的人类可读进度输出。如果本地进度报告也被抑制(例如,通过 push
-q
,或者如果 stderr 未输出到 tty),send-pack 客户端应该(SHOULD)响应 quiet 功能以抑制服务器端进度报告。
push-options
如果服务器发送 push-options 功能,则表示它能够在更新命令发送之后但在包文件流式传输之前接受推送选项。如果推送客户端请求此功能,服务器会将这些选项传递给处理此推送请求的 pre- 和 post-receive 钩子。
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 客户端绝不能(MUST NOT)发送 push-cert 数据包。
session-id=<session-id>
服务器可以声明一个会话 ID,该 ID 可用于在多个请求中识别此进程。客户端也可以向服务器声明自己的会话 ID。
会话 ID 对于给定进程应该是唯一的。它们必须符合 pkt-line 格式,并且不能包含不可打印或空白字符。当前实现使用 trace2 会话 ID(详见 api-trace2),但这可能会改变,会话 ID 的用户不应依赖此事实。