diff options
| author | Danilo M. <danix@danix.xyz> | 2026-06-23 11:29:32 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-06-23 11:29:32 +0200 |
| commit | 23bf41452709a632a7f1afe2d78551da767d8d56 (patch) | |
| tree | a0bad5559cd48dd60043cb7bfe2fdb7c955b24f1 | |
| parent | 28f702c646d9ec4c73010f6e3564941ace412d83 (diff) | |
| download | gitctl-23bf41452709a632a7f1afe2d78551da767d8d56.tar.gz gitctl-23bf41452709a632a7f1afe2d78551da767d8d56.zip | |
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
| -rw-r--r-- | TODO.md | 41 |
1 files changed, 28 insertions, 13 deletions
@@ -16,24 +16,39 @@ Touches three writers, so it is the inverse of `repo create`: 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 must `rm -rf REPO_BASE/<name>.git` (validate_url first; - guard against empty/`..` - validate_url already does, but double check the - final path is under REPO_BASE before rm). + 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/<name>.git TRASH_DIR/<name>.git.<timestamp>`. 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 <days>` 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. Always confirm, show what will be removed. The `-y` flag from +- 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 data is not the same as auto-confirming an additive - conf diff. + 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. -- No undo. The cgitrc backup covers the cgit block; the bare repo is gone for - good once rm runs. Consider moving to a trash dir instead of rm -rf, or at - least refusing if the repo has refs unless `--force`. -- Order: remove cgit block + bare repo via helper first (reversible-ish), then - the gitolite stanza push? Or stanza first? Decide and document - partial - failure (push fails after rm) should leave a clear, resumable state like - create does. +- 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 |
