Expand description
The empty subvolume made at the destination of a git worktree add before Git runs, and its cleanup.
What:
The empty btrfs subvolume the wrapper makes at the destination of a git worktree add, before real Git runs, and
the cleanup of it when Git leaves it empty.
Why:
A worktree that is a subvolume is a source of a later snapshot with no migration, and it is removed in one
call. Git accepts an existing empty directory as the destination and fills it, and an empty subvolume is an
empty directory (doc/planning/cli-git-btrfs-worktree.md, “Creating new worktrees as subvolumes”). Git removes the
destination again only when it created it and failed late; a failure before that point (a branch that exists, a
name Git rejects) leaves the directory, so the wrapper removes the empty subvolume itself. A destination that is
not on btrfs, or a subvolume the kernel refuses, leaves Git to make its ordinary directory without a word to the
person, with one diagnostic line for the log.
In TS you’d write (pseudocode):
const made = await prepareSubvolumeDestination(plan); // undefined: Git makes the directory
await runGit();
if (made) await settleSubvolumeDestination(made); // rmdir when still emptyStructs§
- Created
Subvolume - What: An empty subvolume this process created at a destination. Why: Only a destination the wrapper created is the wrapper’s to remove again.
Functions§
- prepare_
subvolume_ destination - What:
Create the destination of a planned
git worktree addas an empty subvolume, when it can be one.Option<CreatedSubvolume>is the created subvolume or nothing. Why: The destination must be absent (an existing one is Git’s to accept or refuse) and its parent must be on btrfs. The creation ioctl is unrestricted for a regular user, so a refusal is a fault the log keeps and Git’s ordinary directory replaces. - settle_
subvolume_ destination - What:
After Git ended, remove the created subvolume if it is still the one this process created and still empty.
rmdirdeletes an empty subvolume without theuser_subvol_rm_allowedmount option. Why: Git leaves an empty destination when it failed before it started to fill it, and a leftover empty subvolume would make the next attempt at the same path look like an accepted empty directory. A destination that holds anything is Git’s result (or its late failure’s) and stays, and so does an object that another process put at the path: the identity recorded at creation must still be the identity of what the name leads to, and the emptiness is read through the descriptor of that object. The last step names the entry in the held parent, andrmdirremoves only an empty directory, so a swap in that instant could remove only an empty directory, never data.