1# forge repo rm and ssh rm take a repo off the forge: clones, pages, sites2# and previews go, the bare repo waits in the trash, forge repo restore3# brings back the newest removal, and gc empties the trash after4# FORGE_TRASH_DAYS. Only the owner may rm over ssh, and a private repo you5# can't read isn't there to remove.6. "$(dirname "$0")/../lib.sh"7user dami8user ana9repo dami/greet10mkdir -p "$FORGE_ROOT/dami/greet.git/forge" && echo ana >"$FORGE_ROOT/dami/greet.git/forge/collaborators"11clone dami dami/greet "$T/w/d"12at "$T/w/d" commit "first"13at "$T/w/d" git switch -q -c dami/topic14at "$T/w/d" commit "topic"15ok push_as dami "$T/w/d" origin main dami/topic "$(site_commit "$T/w/d" docs):refs/sites/docs" "$(site_commit "$T/w/d" preview):refs/site-previews/docs/dami/topic"16build17exists "$FORGE_WWW/dami/greet/index.html"18exists "$FORGE_WWW/sites/dami/greet/docs/index.html"19exists "$FORGE_WWW/previews/dami/greet/docs/dami~topic/index.html"20has "$FORGE_WWW/repos.json" '"dami/greet"'2122# Without --yes it says what would go, and nothing does.23fails_with "takes it off the forge" ssh_as dami rm dami/greet24exists "$FORGE_ROOT/dami/greet.git/HEAD"25# Collaborators can't; a private repo you can't read looks missing.26fails_with "only dami can remove dami/greet" ssh_as ana rm dami/greet --yes27repo --private dami/secret28fails_with "^forge: no repo dami/secret$" ssh_as ana rm dami/secret --yes29fails_with "^forge: no repo dami/nothing$" ssh_as ana rm dami/nothing --yes3031ok ssh_as dami rm dami/greet --yes32missing "$FORGE_ROOT/dami/greet.git"33missing "$FORGE_WWW/dami/greet"34missing "$FORGE_WWW/sites/dami/greet"35missing "$FORGE_WWW/previews/dami/greet"36fails_with "does not appear to be a git repo" fetch_ssh dami dami/greet37eq "$(ls "$FORGE_ROOT/.forge/trash/dami" | grep -c '^greet\.git\.')" 138build -39lacks "$FORGE_WWW/repos.json" '"dami/greet"'4041# The name is free again; restore won't overwrite what took it.42repo dami/greet43fails_with "dami/greet exists" forge repo restore dami/greet44ok forge repo rm dami/greet45eq "$(ls "$FORGE_ROOT/.forge/trash/dami" | grep -c '^greet\.git\.')" 246# The newest removal comes back: the empty repo, not the first one.47ok forge repo restore dami/greet48exists "$FORGE_ROOT/dami/greet.git/hooks/pre-receive"49fails git --git-dir="$FORGE_ROOT/dami/greet.git" rev-parse -q --verify refs/heads/main50eq "$(ls "$FORGE_ROOT/.forge/trash/dami" | grep -c '^greet\.git\.')" 15152# gc keeps the trash for FORGE_TRASH_DAYS, then empties it.53ok forge gc --age 054eq "$(ls "$FORGE_ROOT/.forge/trash/dami" | grep -c '^greet\.git\.')" 155ok env FORGE_TRASH_DAYS=0 "$FORGE" gc --age 056output | grep -q '^removed trash dami/greet\.git\.' || fail "gc removed no trash"57eq "$(ls "$FORGE_ROOT/.forge/trash/dami" | grep -c '^greet\.git\.' || true)" 05859# A dotted name removed twice, likely within one second: two entries side60# by side, never one inside the other, and restore takes the newer.61repo dami/klot.ski62git --git-dir="$FORGE_ROOT/dami/klot.ski.git" config forge.mark first63ok forge repo rm dami/klot.ski64repo dami/klot.ski65git --git-dir="$FORGE_ROOT/dami/klot.ski.git" config forge.mark second66ok forge repo rm dami/klot.ski67eq "$(ls "$FORGE_ROOT/.forge/trash/dami" | grep -c '^klot\.ski\.git\.')" 268eq "$(find "$FORGE_ROOT/.forge/trash" -mindepth 3 -maxdepth 3 -name '*.git.*' | wc -l | tr -d ' ')" 069ok forge repo restore dami/klot.ski70eq "$(git --git-dir="$FORGE_ROOT/dami/klot.ski.git" config forge.mark)" second