aboutsummaryrefslogtreecommitdiffstats
path: root/TODO.md
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-06-23 11:29:32 +0200
committerDanilo M. <danix@danix.xyz>2026-06-23 11:29:32 +0200
commit23bf41452709a632a7f1afe2d78551da767d8d56 (patch)
treea0bad5559cd48dd60043cb7bfe2fdb7c955b24f1 /TODO.md
parent28f702c646d9ec4c73010f6e3564941ace412d83 (diff)
downloadgitctl-master.tar.gz
gitctl-master.zip
docs: delete-repo moves to a trash dir, not rm; cron-prune laterHEADmaster
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Diffstat (limited to 'TODO.md')
-rw-r--r--TODO.md41
1 files changed, 28 insertions, 13 deletions
diff --git a/TODO.md b/TODO.md
index 6b98eb9..4c4a26e 100644
--- a/TODO.md
+++ b/TODO.md
@@ -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