feat: one repos.yml entry can be a folder of repos - #32
Merged
Conversation
`- folder: ~/repos/jebel-quant` puts every checkout sitting directly inside that directory on the board. Sixteen lines become one, and the one cannot drift out of step with the disk the way sixteen can: clone a repo into the folder and it joins at the next restart, delete it and it leaves. This is not the whole-root directory walk that the explicit list replaced. That walk took any checkout anywhere under one mount whose origin happened to look plausible, and nobody had said where to look. A folder is a directory you wrote down, read one level deep and no further - `folder: ~` finding your entire disk is exactly the failure the one-level rule exists to prevent, and it is also why `folder: ~/repos` correctly finds nothing when the checkouts live at `~/repos/<org>/<name>`. The refusals follow what a `path` entry already does, for the same reason: a board that is quietly short a folder's worth of repos is worse than one that did not come up. A folder that is not there, or that holds no checkouts at all, stops the collector. What is *not* fatal is a clone inside the folder with no usable origin remote - somebody's scratch clone, warned about and skipped, because a folder entry is not the deliberate statement that naming a path is. A `path` to that same clone is still refused. An entry of its own wins, and the dedupe that makes that work is on the checkout path rather than on `namespace/name`. A folder leaves out any checkout another entry names by `path`, so one repo inside a listed folder keeps a `repo:` override for its upstream - and the whole point of such an override is that the name comes out different, which is why matching on the name cannot do it. Where the collision really is on the name (`- repo: org/x` beside the folder org/x is checked out in), the two merge into one repo either way round: the entry decides the name and the forge, the folder still supplies the path it found. Verified against the real fleet on this machine: two folders plus a `path` override plus a bare `repo:` resolve to 11 repos, with the override renamed and the bare entry picking up a checkout path it could not previously express. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
- folder: ~/repos/jebel-quantputs every checkout sitting directly inside thatdirectory on the board. Sixteen lines become one, and the one cannot drift out
of step with the disk the way sixteen can: clone a repo into the folder and it
joins at the next restart, delete it and it leaves.
Not the walk we removed
The old board was assembled by a whole-org GitHub sweep plus a directory walk
under one mounted root, and both decided membership on their own. A folder is a
directory you wrote down, read one level deep and no further.
folder: ~finding your entire disk is exactly the failure the one-level rule prevents —
and it is also why
folder: ~/reposcorrectly finds nothing when the checkoutslive at
~/repos/<org>/<name>.The refusals
They follow what a
pathentry already does, for the same reason: a boardquietly short a folder's worth of repos is worse than one that did not come up.
originThe last one is the only softening. That is somebody's scratch clone, and a
folder entry is not the deliberate statement that naming a path is — a
pathto that same clone is still fatal. A folder of nothing but such clones still
refuses, since the file said something and none of it survived.
An entry of its own wins
The dedupe is on the checkout path, not on
namespace/name. A folder leavesout any checkout another entry names by
path, so one repo inside a listedfolder keeps a
repo:override for its upstream:Matching on the name could not do that, because the whole point of the override
is that the name comes out different. Where the collision really is on the name
(
- repo: org/xbeside the folderorg/xis checked out in), the two mergeinto one repo either way round: the entry decides the name and the forge, the
folder still supplies the path it found. Two folders holding clones of the same
repo remain a refusal — there is no saying which checkout the board means.
forge: gitlabon a folder covers every checkout it turns up, validated onceagainst the line that was written rather than per checkout found.
Verification
repos.pyat 100% statement coverage; ruff check and formatclean.
pathoverride plus a bare
repo:resolve to 11 repos, with the override renamedand the bare entry picking up a checkout path it could not previously
express.
folder:in it, and the container needsno new mount — the single read-only
$HOMEmount already covers folders.Docs,
repos.example.yml, README anddocs/index.mdupdated, including the"nothing is discovered" claim, which now reads "nothing is discovered behind
your back: a repo is on the board because
repos.ymlnames it — or names thefolder you keep it in".
🤖 Generated with Claude Code