Documentation
¶
Overview ¶
Command clonescan says, for each local git repository under the directories it is given, whether deleting it would lose anything:
clonescan ~/src clonescan --depth 3 --bundle ~/Backups/clones ~/src ~/work
It is read-only. Each repository is reported SAFE or KEEP, with the reasons: uncommitted paths, stashes, branch commits that are on no remote and are not the head of a merged pull request, detached commits, the worktrees that hang off it, and how long ago its HEAD last moved.
It replaces a throwaway program that swept stale clones on 2026-10-18 and 2026-10-20, and keeps what that program learned:
- ⛔ A SQUASH MERGE MAKES "UNPUSHED" MEANINGLESS. The commits of a branch merged by squash are on no remote once GitHub deletes the branch, and the work is safe. So a branch is safe when its tip is reachable from a remote-tracking ref, OR when it is the head of a MERGED pull request whose headRefOid equals the local tip. A tip that moved on after the merge has commits nobody merged.
- ⛔ THREE "CLONES" WERE WORKTREES. Their `.git` is a FILE holding `gitdir: …/.git/worktrees/<name>` (gitrepository-layout(5)), and their metadata lives inside the main repository: deleting the main first destroyed it. A worktree is reported under its main repository, never as a clone of its own, and a main repository with a worktree hanging off it is never SAFE.
- The age of the last HEAD movement shows whether a peer session is working in a clone: a HEAD that moved within --recent is KEEP.
There is no flag that deletes. Deleting stays a human act: this reads a repository at one instant, and a peer session can commit into it the next.
Exit status: 0 every repository is SAFE; 1 at least one is KEEP (or a bundle failed its check); 2 a usage error or a repository that could not be read.