设置和配置
获取和创建项目
基本快照
分支与合并
共享和更新项目
检查和比较
打补丁
调试
电子邮件
外部系统
服务器管理
指南
管理
底层命令
- 2.44.1 → 2.52.0 无更改
-
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] 文档。 |
服务器应支持本文档中定义的所有功能。
在 receive-pack 和 upload-pack 的初始服务器响应的第一行,第一个引用后面跟着一个 NUL 字节,然后是一个空格分隔的服务器功能列表。这些允许服务器向客户端声明它能支持什么,不能支持什么。
客户端随后将发送一个空格分隔的功能列表,它希望生效。客户端不得请求服务器未声明支持的功能。
服务器在收到不理解的功能时必须诊断并中止。服务器不得忽略客户端请求且服务器已声明的功能。因此,服务器不得声明它不理解的功能。
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 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,客户端会以 S-R-Q 交错的方式发送 c-b-a 链。
multi_ack_detailed
这是 multi_ack 的扩展,允许客户端更好地理解服务器的内存状态。有关更多信息,请参阅 gitprotocol-pack[5],第“Packfile Negotiation”节。
no-done
此功能仅应与智能 HTTP 协议一起使用。如果同时存在 multi_ack_detailed 和 no-done,则发送者可以在发送第一个“ACK obj-id ready”消息后立即发送 packfile。
在智能 HTTP 协议中,如果没有 no-done,服务器会话将结束,客户端必须进行另一次往返发送“done”后,服务器才能发送 packfile。no-done 消除了最后的往返,从而稍微降低了延迟。
thin-pack
thin pack 是一种包含 delta,其基对象未包含在 packfile 中(但接收端已知存在)的 packfile。这可以显著减少网络流量,但要求接收端知道如何通过添加缺失的基对象来“加厚”这些 packfile。
upload-pack 服务器在能够生成和发送 thin pack 时宣告 thin-pack。客户端在知道如何“加厚”它时请求 thin-pack 功能,通知服务器它可以接收这样的 packfile。如果客户端无法将 thin pack 转换为独立的 packfile,则不得请求 thin-pack 功能。
另一方面,receive-pack 默认假定能够处理 thin pack,但可以通过宣告 no-thin 功能要求客户端不使用此功能。如果服务器宣告了 no-thin 功能,客户端不得发送 thin pack。
这种不对称的原因是历史性的。receive-pack 程序是在 thin pack 发明之后才出现的,因此历史上 receive-pack 的参考实现一直支持 thin 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 通过 packfile 中的位置而不是 obj-id 来引用其基对象。也就是说,它们可以在 packfile 中发送/读取 OBJ_OFS_DELTA(又名类型 6)。
agent
服务器可以选择性地发送 agent=X 形式的功能,以通知客户端服务器正在运行 X 版本。客户端可以选择性地通过响应 agent=Y 功能来返回自己的 agent 字符串(但如果服务器未提及 agent 功能,则不得这样做)。X 和 Y 字符串可以包含除空格(即字节范围 32 < x < 127)以外的任何可打印 ASCII 字符,并且通常采用“package/version”(例如,“git/1.8.3.1”)的形式。agent 字符串纯粹用于统计和调试目的,不得用于以编程方式假设特定功能的存在或缺失。
object-format
此功能以哈希算法作为参数,表示服务器支持给定的哈希算法。它可以被发送多次;如果是这样,第一个给定的是在 ref 广告中使用的那个。
当由客户端提供时,这表示它打算使用给定的哈希算法进行通信。提供的算法必须是服务器支持的算法。
如果未提供此功能,则假定唯一支持的算法是 SHA-1。
symref
此参数化功能用于告知接收者哪个符号引用指向哪个引用;例如,“symref=HEAD:refs/heads/master”告诉接收者 HEAD 指向 master。此功能可以重复以表示多个符号引用。
如果 HEAD 符号引用是发送的引用之一,则服务器应包含此功能。
客户端可以使用此功能的参数来选择克隆仓库时的正确初始分支。
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”或类似方式启动,并且不希望接收 side band 2。基本上,客户端只是说“我不想在 sideband 上接收流 2,所以请不要发送给我,如果你发送了,我也会忽略它”。但是,sideband 通道 3 仍然用于错误响应。
include-tag
include-tag 功能是指在发送对象时,也发送指向这些对象的注解标签。如果我们向客户端打包一个对象,而一个标签对象恰好指向该对象,那么我们也会打包该标签对象。通常,这允许客户端在获取分支时,在单个网络连接中获取所有新的注解标签。
客户端总是可以发送 include-tag,将其硬编码到请求中,当服务器宣告此功能时。客户端是否请求 include-tag 只取决于客户端对标签数据的需求,而与服务器是否在 refs/tags/* 命名空间中宣告了对象无关。
如果服务器打包了标签,并且客户端请求了 include-tags,则服务器必须打包这些标签。
客户端必须准备好服务器忽略 include-tag 并且实际上未在 packfile 中发送标签的情况。在这种情况下,客户端应发出后续的 fetch 来获取 include-tag 本来会提供的标签。
如果服务器支持 include-tag,则应发送它,无论是否有可用标签。
report-status
receive-pack 进程可以接收 report-status 功能,该功能告诉它客户端在 packfile 上传和引用更新后想要一份报告。如果推送的客户端请求此功能,在解包和更新引用后,服务器将响应 packfile 是否成功解包以及每个引用是否成功更新。如果其中任何一个不成功,它将发送错误消息。有关示例消息,请参阅 gitprotocol-pack[5]。
report-status-v2
report-status-v2 功能通过添加新的“option”指令扩展了 report-status 功能,以支持由“proc-receive”挂钩重写的引用。“proc-receive”挂钩可以处理伪引用的命令,该命令可能创建或更新具有不同名称、新 OID 和旧 OID 的引用。而 report-status 功能无法报告这种情况。有关详细信息,请参阅 gitprotocol-pack[5]。
quiet
如果 receive-pack 服务器宣告了 quiet 功能,它就能够抑制原本在处理接收到的 packfile 时可能显示的、面向人类的可读进度输出。send-pack 客户端应响应 quiet 功能来抑制服务器端进度报告,如果本地进度报告也被抑制(例如,通过 push -q,或者如果 stderr 未连接到 tty)。
push-options
如果服务器发送 push-options 功能,则它能够在发送更新命令之后,但在 packfile 流式传输之前,接受 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> 包含在推送证书中。send-pack 客户端不得发送 push-cert 数据包,除非 receive-pack 服务器宣告了此功能。
filter
如果 upload-pack 服务器宣告 filter 功能,fetch-pack 可能会发送“filter”命令来请求部分克隆或部分获取,并请求服务器从 packfile 中省略各种对象。
session-id=<session-id>
服务器可以宣告一个会话 ID,用于跨多个请求识别此进程。客户端也可以将其自己的会话 ID 回传给服务器。
会话 ID 应该在给定进程中是唯一的。它们必须适合一个 packet-line,并且不得包含不可打印字符或空格字符。当前实现使用 trace2 会话 ID(有关详细信息,请参阅 api-trace2),但这可能会发生变化,会话 ID 的用户不应依赖此事实。