Runxi Yu Asked: 2025-02-19 11:12:13 +0800 CST2025-02-19 11:12:13 +0800 CST 2025-02-19 11:12:13 +0800 CST 旧对象 ID 在接收后挂钩期间是否保证有效? 772 如果发生强制推送或分支删除,则 ref 指向的旧对象可能不再被任何 ref 引用,从而有资格进行垃圾收集。 在这种推送的 git post-receive 钩子的持续时间内,旧对象是否保证仍然有效? git 2 个回答 Voted LeGEC 2025-02-19T16:47:40+08:002025-02-19T16:47:40+08:00 我认为@j6t 的观点是正确的:我认为没有正式的保证。 话虽这么说:代码试图明确这一点。 您可以查看服务器端操作的实现receive-pack(代码来自v2.48.1): int cmd_receive_pack(int argc, // l.2503 ...) { [...] run_receive_hook(commands, "post-receive", 1, // l.2610 &push_options); [...] if (auto_gc) { // l.2615 struct child_process proc = CHILD_PROCESS_INIT; if (prepare_auto_maintenance(1, &proc)) { [...] 并注意到钩子的执行post-receive(l.2610)发生在对“auto_gc”操作的明确调用之前(代码块从l.2615开始)。 因此,如果您的post-receive钩子是同步的,则此 autogc 操作将不会在运行钩子之前删除过时的提交。 git在其数据库上还具有基本的锁定机制,以防止并发操作做坏事,所以我认为在执行你的钩子期间其他gc 操作会被拒绝(虽然我没有在这个答案中提供这一点的证据)。 Best Answer j6t 2025-02-19T15:40:29+08:002025-02-19T15:40:29+08:00 没有正式保证悬垂对象仍然有效,因为不可能知道接收后钩子(或任何命令)何时git完成其操作。 唯一存在的规定是,垃圾收集将在对象变为悬空状态后为其提供“短暂的生命周期”。这里的“短暂”是指两周,并且是可配置的。目的是让这个时间跨度足以让任何正在进行的git命令完成并停止使用悬空对象。
我认为@j6t 的观点是正确的:我认为没有正式的保证。
话虽这么说:代码试图明确这一点。
您可以查看服务器端操作的实现
receive-pack
(代码来自v2.48.1):并注意到钩子的执行
post-receive
(l.2610)发生在对“auto_gc”操作的明确调用之前(代码块从l.2615开始)。因此,如果您的
post-receive
钩子是同步的,则此 autogc 操作将不会在运行钩子之前删除过时的提交。git
在其数据库上还具有基本的锁定机制,以防止并发操作做坏事,所以我认为在执行你的钩子期间其他gc 操作会被拒绝(虽然我没有在这个答案中提供这一点的证据)。没有正式保证悬垂对象仍然有效,因为不可能知道接收后钩子(或任何命令)何时
git
完成其操作。唯一存在的规定是,垃圾收集将在对象变为悬空状态后为其提供“短暂的生命周期”。这里的“短暂”是指两周,并且是可配置的。目的是让这个时间跨度足以让任何正在进行的
git
命令完成并停止使用悬空对象。