workspace_collect_repos silently skips dot-named repo roots (e.g. Forgejo .profile, GitHub .github) #113

Closed
opened 2026-07-24 14:58:36 +01:00 by vnprc-agent · 0 comments
Contributor

Problem

workspace_collect_repos in lib/workspace.sh enumerates checkouts by globbing "$dir"/*/, which does not match leading-dot directory names (bash * skips dotfiles unless dotglob is set). Both pull-all and work-diff build their repo list from this one helper, so any checkout whose directory name starts with a dot is silently invisible to both: it is never synced by pull-all and never appears in work-diff, with no error to explain the omission.

Why it matters

Reserved dot-prefixed repository names are a normal part of the Git-forge ecosystem, so downstream adopters will hit this, not only us:

  • GitHub: .github — org default community-health files and, via profile/README.md, the org profile page.
  • Gitea / Forgejo: .profile — user and org profile README — and .profile-private — the members-only org profile variant.

Anyone who checks one of these out on a dev VM to edit it will find it present but never pulled and never shown in work-diff.

Current workaround

The problem can be sidestepped per-repo by decoupling the registry checkout from the remote: fetch from the .profile remote but check out to a non-hidden path such as org-profile. That keeps the forge repo name intact — renaming .profile would break the profile-page feature — while staying visible to the workspace tools, and it works because bootstrap-vm.sh already treats remote and checkout as independent. It is per-repo and easy to forget, which is the motivation to handle dot-repos in the collector directly.

Proposed fix

Teach workspace_collect_repos to include dot-named repo roots. Because pull-all and work-diff share this single helper, one fix covers both. Care is needed so the recursion never descends into git internals: enabling dotglob (or adding a "$dir"/.*/ glob) must skip ., .., and .git, and a hidden directory should be included only when it is itself a repo root — never recursed into as an intermediate container. A regression test with a .profile-style checkout fixture under a temp workspace would lock the behavior in.

Once this lands, any non-hidden-checkout workaround can optionally revert to the real dot name for parity, though it is harmless to leave in place.

## Problem `workspace_collect_repos` in `lib/workspace.sh` enumerates checkouts by globbing `"$dir"/*/`, which does not match leading-dot directory names (bash `*` skips dotfiles unless `dotglob` is set). Both `pull-all` and `work-diff` build their repo list from this one helper, so any checkout whose directory name starts with a dot is silently invisible to both: it is never synced by `pull-all` and never appears in `work-diff`, with no error to explain the omission. ## Why it matters Reserved dot-prefixed repository names are a normal part of the Git-forge ecosystem, so downstream adopters will hit this, not only us: - GitHub: `.github` — org default community-health files and, via `profile/README.md`, the org profile page. - Gitea / Forgejo: `.profile` — user and org profile README — and `.profile-private` — the members-only org profile variant. Anyone who checks one of these out on a dev VM to edit it will find it present but never pulled and never shown in `work-diff`. ## Current workaround The problem can be sidestepped per-repo by decoupling the registry `checkout` from the `remote`: fetch from the `.profile` remote but check out to a non-hidden path such as `org-profile`. That keeps the forge repo name intact — renaming `.profile` would break the profile-page feature — while staying visible to the workspace tools, and it works because `bootstrap-vm.sh` already treats `remote` and `checkout` as independent. It is per-repo and easy to forget, which is the motivation to handle dot-repos in the collector directly. ## Proposed fix Teach `workspace_collect_repos` to include dot-named repo roots. Because `pull-all` and `work-diff` share this single helper, one fix covers both. Care is needed so the recursion never descends into git internals: enabling `dotglob` (or adding a `"$dir"/.*/` glob) must skip `.`, `..`, and `.git`, and a hidden directory should be included only when it is itself a repo root — never recursed into as an intermediate container. A regression test with a `.profile`-style checkout fixture under a temp workspace would lock the behavior in. Once this lands, any non-hidden-checkout workaround can optionally revert to the real dot name for parity, though it is harmless to leave in place.
vnprc closed this issue 2026-07-25 18:18:09 +01:00
Sign in to join this conversation.
No description provided.