Conversation
Spawn-prep filled a per-task clone's submodules by fetching each one from its forge-resolved URL — paid by every task on the repo, and for a large submodule it dominates spawn-prep, while the superproject itself is nearly free (`clone --local` hardlinks the cache's objects). When the repo's `git_url` names a checkout on this host, that checkout already holds every submodule's objects, so clone them from it instead: a local clone with a hardlinked object store and no network. The donor is matched by path, never by URL (the donor and the per-task clone resolve relative `.gitmodules` URLs against different origins), so hydration walks the tree a level at a time — init, override the resolved URL with the donor's checkout, update this level, recurse — and finishes with one `submodule sync --recursive` that puts the canonical URLs back in the config and in each submodule's own origin. It is only an optimisation: no local checkout, a raise, or a submodule still uninitialized afterwards all fall back to the plain recursive update, which is exactly what a repo without a donor gets. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…odule-hydration # Conflicts: # AGENTS.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Spawn-prep filled a per-task clone's submodules by fetching each one from its forge-resolved URL — paid by every task on the repo. For a repo with a large submodule that dominates spawn-prep, while the superproject itself is nearly free (
clone --localhardlinks the cache clone's objects).When the repo's
git_urlnames a checkout on this host, that checkout already holds every submodule's objects, so spawn-prep now clones them from it: a local clone with a hardlinked object store and no network.The donor is matched by path, never by URL — the donor resolved its relative
.gitmodulesURLs against its ownoriginwhile the per-task clone resolves them againstgit_url, so the same submodule can legitimately carry two different URLs. Per superproject level:submodule init— git resolves the declared URLs into config;submodule updatefor this level only — a nested submodule's URL can't be resolved, let alone redirected, before its parent exists;Then, once at the top,
submodule sync --recursiverestores the canonical URLs — in the config and in each submodule's ownorigin— so no donor path reaches the container.It is only an optimisation, never a precondition: no local checkout, a raise, or any submodule still uninitialized afterwards all fall back to the plain
submodule update --init --recursive, which is exactly what a repo without a donor gets. Repos whosegit_urlis a hosted forge are unchanged; giving them a donor by making the cache clone submodule-aware stays backlogged.ADR 0011 gains §1c for the mechanism and its fallback rule.
Plan: the task's
plan.mdartifact.