Docs/CLI reference

CLI reference

tama copies

Opens the command group that reports and removes the second full checkouts under roots you name, because a repository copy is a checkout of a repository you already have that git knows nothing about.

Opens the command group that reports and removes the second full checkouts under roots you name, because a repository copy is a checkout of a repository you already have that git knows nothing about.

#Invocation

tama copies <command>

Commands:
  list   [--root <PATH>]... [--json]                     Every second full checkout under the roots
  remove [--root <PATH>]... [--except <PATH>]... [--only <PATH>]... [--apply] [--force] [--json]  Remove them; previews unless --apply

<command> is required and must be one of the two linked leaves below.

#Command tree

#The noun this group owns

block-repository-copies refuses two nouns, and until this group existed only one of them could be reclaimed:

  • A linked worktree is a checkout whose .git is a file pointing into the owning repository's .git/worktrees/<name>. Git tracks it, and tama worktrees removes it.
  • A repository copy is another checkout, a submodule checkout or a bare dependency cache. Git does not register these as linked worktrees, so git worktree remove cannot reclaim them. The copies group reports them even inside ignored package-manager and build directories.

A pass reports every linked worktree it crosses and never removes one, so a clean copies pass cannot read as "one checkout per repository" when it is not.

#What a pass proves before deleting anything

A copy goes by deleting its directory, which git cannot undo and no remote can restore, so each candidate is judged first. In this order, one sentence each:

  • uncommitted-changes — git status --porcelain prints something.
  • commits-not-on-remote — commits at HEAD or on local branches are absent from the repository's remote-tracking refs.
  • no-origin-remote — nothing to compare against.
  • no-canonical-checkout — no checkout of the same repository sits under the roots given, so this directory is the only one here. --only is how an operator answers that one.
  • owns-linked-worktrees — deleting it would orphan git's records in .git/worktrees; remove those first with tama worktrees remove.

A candidate git will not answer for at all is reported under unreadable and never removed.

#--except and --only are remove options, and never both

--except spares one copy: it is not removed, not counted as removable, and never produces a refusal. --only narrows the pass to the paths it names and accepts them as removable even when they are the sole checkout of their repository here — every refusal that protects history still applies to them. They are two answers to the same question, so a command carrying both is a usage error, and so is a value that matches no copy the pass found.

A named pass reads canonical repository headers at the roots and their direct children, then walks only the named copy subtrees. It does not descend into unrelated directories. Read failures within that required scope still prevent every deletion, even with --force; a successful named pass is not a complete inventory of the roots.

#Two checkouts of one repository, both at the top

Two directories directly under a root can share an origin: for example, Wisent/wisent-compute and Wisent/stado can both be checkouts of github.com/wisent-ai/stado. A pass reports that pair and removes neither, because which one to keep is the operator's call and a sort order would have deleted 69 GB of the tree the product is built from.

#--root has no default, deliberately

--root is repeatable and required at least once on both leaves. Omitting it is a usage error, not a full-machine walk:

tama copies needs at least one --root; a machine-wide default would walk directories Tama does not own.

The named root itself is a canonical checkout, never a candidate: naming one repository as the root reports the clones inside it, not the repository.

#Discovery and authority

For list and unrestricted removal, the deep repository walk includes every named root and ignores no directory name except Git's .git metadata. Package-manager checkouts, submodules and bare Git caches are included. Content scans keep their own filtered walk; they do not decide what a cleanup inventory may omit. Canonical checkouts from all roots are collected before ownership is resolved, so root order cannot change whether a known canonical checkout is found. Git supplies working-tree state, history and origin; a .git file alone does not distinguish a submodule from a linked worktree.

#Output and state

The group itself performs no action and takes no options. list and a bare remove mutate nothing; only remove --apply deletes anything, and it is all-or-nothing: a pass with any refusal outstanding removes none of the copies it selected. Both leaves print a text report by default and an exact JSON document under --json, and both are also answered by tama request copies/list and tama request copies/remove (tama request), which is what the Copies screen of Tama Desktop runs.

#Refusals and failures

Exit 0 is success, exit 1 is an operational failure or a refused --apply, and exit 2 is a usage error — a missing or unknown leaf, a leaf invoked without --root, --except together with --only, or either of them naming a path this pass did not find. Each leaf page carries its own exact refusal sentences.

Return to the complete CLI command tree.