Rename or move a tracked file

tovio mv, and why the move is recorded rather than guessed.

Written By Dustin

Last updated 32 minutes ago

tovio mv <from> <to>tovio rename <from> <to>   # the same command

Moves the working file now and records the move as one op-log operation, so tovio undo reverses it. The next commit folds the move into its move set.

Why not just move the file

TOVIO does auto-detect renames on commit — exactly (content-identical) for free, and by content similarity above a threshold otherwise. The threshold defaults to 0.5 and is tunable with tovio config set rename.similarity <value>. The accepted range is above 0.0 and up to 1.0; 0.0, a negative value or anything non-numeric is ignored and the default stands, so a typo never silently disables rename detection.

tovio mv records the move regardless of similarity. That is the reason to use it: a heavily-rewritten move is still tracked as a rename, and a rename is a fact rather than a heuristic.

This matters for two things in particular:

  • Blame across a rename stays correct, because there is nothing to infer.
  • Rename conflicts are typed. If you rename a file and a colleague renames it differently, that is a rename-rename conflict with its own resolution (tovio resolve <path> --rename-to <path>) rather than an ambiguous mess.

When it refuses

  • No file at the source. mv moves a real working file; there is nothing to move otherwise.
  • The destination already exists. It will not overwrite.
  • The source is not the file's exact on-disk path. On a case-insensitive or normalizing filesystem, config/PROD.ENV can resolve to config/prod.env; the move is refused rather than letting a spelling variant slip past a policy that matches the real path.
  • Protected to unprotected. Moving a policy-covered file to a clear path would write its plaintext into the tracked tree — a declassification — and is refused. Move it to another protected path, or remove the covering policy deliberately first.

Moving into a protected path

Clear to protected, and protected to protected, are both allowed: the commit's snapshot re-seals the content under the destination's policy. Be aware that this commits as a re-seal (delete + add), not as a tracked rename — no protected path is carried in a commit's move set. mv says so on stdout, and --json reports it as "resealed": true.

Check the destination before moving something sensitive:

tovio policy show <path>