Expand description
The paths of a migration and the refusals that stop it before anything is created.
What:
The paths of one migration and the refusals that stop it before anything is created: every refusal names its cause
and every remedy that applies.
Why:
Converting a checkout swaps its directory under every process and worktree, so the migration starts only when the
filesystem, the checkout and the state left by an earlier run allow it. The conditions are those of the proven
script (doc/handover/cli-git-subvolume-migration-script.md, “Refusals”) with the rest of the owner’s rules:
nothing is spawned, and a refusal is text a person can act on. A condition checks only metadata (the dry run reads
.git and .git/worktrees/*/gitdir, and lists every directory of the tree once to count its entries for the free-space
check, without opening a file).
In TS you’d write (pseudocode):
const refusals: { cause: string; remedy: string }[] = preflight({ platform, layout, journal });Structs§
- Layout
- What: Every path of one migration, derived from the checkout’s path. Why: The new tree and the old tree sit beside the checkout (one parent, so the exchange stays on one filesystem), and the journal and the unreadable-file list sit beside them, outside the tree that is exchanged.
- Refusal
- What: One refusal. Why: The cause says what is wrong with which path; the remedy lists every way forward, so the person never has to guess.
Constants§
- IN_
PROGRESS_ NAMES - The names whose presence in
.gitor in a linked worktree’s administrative directory means Git is mid-operation. - METADATA_
BYTES_ PER_ ENTRY - The metadata the copy writes for one entry, in bytes of the filesystem’s own accounting: the
Metadata, DUPfigure ofbtrfs filesystem df --block-size=1read before and after reflink-copying a tree of 22,719 entries eight times (181,752 entries) on this host, three alternating rounds against a no-copy control of the same wall time: 957.9, 979.0 and 984.8 bytes per entry, while the control moved by at most 9.9 MB against 174 MB to 179 MB for a copy. Rounded up to one kibibyte. Recorded indoc/planning/cli-git-shipped-limits-audit.md, “The free-space preflight”. This is the coordinator’s pick under the owner’s delegation (“Pick options as if I had picked them”), open to the owner’s veto. - METADATA_
COPIES - How many physical copies of the metadata the filesystem keeps: the
DUPprofile of this host writes each metadata byte twice (Metadata ratio: 2.00inbtrfs filesystem usage), and the free space the check reads is physical. A filesystem with a single copy is over-estimated by this factor, which only refuses earlier.
Functions§
- layout_
of - What:
The layout for a checkout path.
A root with no parent or no name (
/) has no layout. Why: The names are fixed by the root’s name, so a rerun finds the same files. - migrate_
refusals - What:
The refusals of a fresh or resumed migration; empty means it may start or continue.
Why:
See the module description. The journal says which leftovers are this migration’s own: the new tree after its
createstep began, the old tree after theexchangestep began,.git/index.lockafter thelockstep began. - remove_
old_ refusals - What: The refusals of deleting the old tree: the migration must have finished and the old tree must exist. Why: The old tree is the only copy of the files this user could not read, and of anything not yet carried over; it is deleted only when the person asks, after a verified migration.
- required_
free_ bytes - What:
The free bytes the migration needs for the metadata of
entriesentries. Why: The copy shares data blocks and writes one metadata record per entry, so the need grows with the entries, not with a fixed floor; the measured cost of an entry and the copies of the metadata are the two named constants above. A count so large that the product overflows saturates at the largestu64, which no filesystem has free, so it refuses. - rollback_
refusals - What: The refusals of a rollback: it needs a journal. Why: Without a record the command cannot tell which directory is the original and which the copy.