# gitctl TODO Planned features. Each note captures the non-obvious bits so the work does not re-discover them. Keep the hard rules from CLAUDE.md (stdlib only, single-file scripts, single-writer repo.desc, idempotent, no em dashes, work on master). ## 1. delete repo `gitctl repo delete ` - remove a repo from all three places it lives. Touches three writers, so it is the inverse of `repo create`: - gitolite.conf stanza -> client edits the admin clone, pushes (needs the SSH key / card, like create). - cgit block in /etc/cgitrc -> new helper verb, the inverse of `insert_repo_block`: find the repo's `repo.url=` line and delete its block up to the next `repo.url=`, `section=`, banner, or EOF. Back up first (write_cgitrc_lines already does). Run sync after. - the bare repo on disk -> gitolite does NOT delete it when the stanza goes away. The helper does NOT rm it. Instead it MOVES the repo to a trash dir (see below), so deletion is reversible and you review before anything is really gone. Trash dir (the chosen design, not rm -rf): - New constant `TRASH_DIR`, OUTSIDE `REPO_BASE` so gitolite and cgit never see it (e.g. `/var/lib/gitolite3/trash`). git-writable. - Delete = `mv REPO_BASE/.git TRASH_DIR/.git.`. Atomic within one filesystem; if TRASH_DIR is on a different mount, fall back to copy+remove or just require same-fs. - validate_url first; double-check the resolved source path is under REPO_BASE before moving (defense in depth, even though validate_url blocks `..`/`/`). - Leave a note for the user: print where it went and that it needs manual review/removal. Optionally drop a short TRASH_DIR/README or a per-entry `.trashinfo` (origin path, timestamp, who) so a later cleanup tool has context. - FUTURE: a helper verb like `gc-trash --older-than ` that prunes TRASH_DIR entries past a retention window, runnable from cron. The move-based design makes this trivial later; do not build it now (YAGNI), just keep TRASH_DIR layout cron-friendly (timestamp in the name). Design notes: - DESTRUCTIVE (even as a move - it disappears from the live tree). Always confirm, show what will be removed and where it goes. The `-y` flag from item 3 must NOT bypass the delete confirmation (or gate it behind a separate, louder opt-in). Deleting is not the same as auto-confirming an additive diff. - Idempotent-ish: if the repo is already gone from a given place, skip that step and report, do not error. - Recoverable: the bare repo sits in TRASH_DIR until you remove it; the cgitrc backup covers the cgit block. Nothing is irreversibly destroyed by gitctl. - Order: remove cgit block + move bare repo via helper first, then the gitolite stanza push? Or stanza first? Decide and document - partial failure (push fails after the move) should leave a clear, resumable state like create does. ## 2. list repos `gitctl repo list` - show repos known to the server, ideally with their section. - New helper verb `list-repos`: parse /etc/cgitrc for `repo.url=` lines and the preceding `section=` (reuse `find_repo_section` / the section-tracking loop). Print `
\t` or similar. - Cheap, read-only, no confirmation. Good first item - unblocks better bash completion (complete repo names for `desc` / `delete` / `add-remote`) and gives `delete` something to validate against. - Alternative source: gitolite (`ssh git_push info` lists repos) but cgitrc is the helper's own domain and already parsed; prefer it. ## 3. `-y` / `--yes` flag on `repo create` Let an agent drive `repo create` without the interactive y/N, so the only human step left is supplying the SSH-key password / smartcard PIN for the push. - Add `--yes` (`-y`) to `repo create`; when set, skip the `_confirm` prompt and proceed to commit + push. - IMPORTANT: `-y` does NOT remove the need for a human at the SSH key. The phase-1 `git push` to gitolite-admin still requires the key's password or the card touch/PIN, which an agent cannot supply. `-y` removes only the y/N diff-confirmation; the push auth is still interactive. Document this clearly so nobody expects fully unattended creation. - Still print the diff before pushing even with `-y` (visibility), just do not block on it. - Consider whether `-y` should also auto-create a missing section (it already does that without asking) - keep behavior consistent. ## Cross-cutting - Bash completion: once `repo list` exists, complete repo names for `desc`, `delete`, `add-remote` (like `--section` is completed today). One ssh call, only when completing a repo-name argument. - Skill: update both SKILL.md files (repo skills/gitctl + ~/.claude) to mention delete (and its destructive, confirm-always nature) and `-y`'s real limit. - Tests: each new helper verb gets self-test coverage (cgit block removal is the risky one - mirror the insert tests: first/middle/last/missing).