Skip to main content

Module worktree_clean

Module worktree_clean 

Source
Expand description

Whether a worktree is clean enough to copy from or to remove without asking Git, proven in process. What: Whether a worktree is clean enough to be copied from, or removed without asking Git: no operation in progress, an index equal to the tree of HEAD, every tracked file unchanged by its recorded size, times and inode, and no untracked file that Git does not ignore. Why: A snapshot or a clone carries the bytes of the source’s files, so any change the source has not committed would reach the new worktree, and a removal by the subvolume ioctl cannot be undone. The tracked-file checks read the index in process (no Git process) with the same comparison Git’s fast path makes, and refuse every shape they cannot prove: a split or sparse index, a skip-worktree or assume-valid entry, a submodule, an entry as new as the index file (Git re-hashes those, so their stat fields prove nothing). The one question the index cannot answer, whether an untracked file is ignored, goes to one git ls-files run. Every refusal returns its reason in words for the log.

In TS you’d write (pseudocode):

const clean = await checkClean({ root, gitDir, commonDir }); // { headCommit, headTree } or throws a reason

Structs§

CleanRefusal
What: Why a worktree could not be proven clean: the kind and the reason in words. Why: The words are for logs and for people; the kind is for code.
CleanSource
What: What a clean worktree’s HEAD names. Why: The two-tree update that follows a snapshot starts from this tree, so a caller needs not read it again.
ContentTarget
What the content decision needs besides the entries: the worktree, its Git directories, the environment and the format.
DirtySource
What: What HEAD names for a worktree that is not clean, and why it is not, once it is known that the only trouble is ordinary changes. Why: The snapshot rung copies such a worktree and restores the copy to its HEAD; the copy’s own index is installed, so the index bytes here are only as read: they name the tracked paths and prove nothing about the files.
StatCursor
What: A walk below a held directory that keeps the last directory it opened. Why: The paths of an index come in order, so most of them share their parent with the one before; one openat2 chain per directory instead of per file is what the walk costs, and each file is still reached through handles that follow no link.
StatEntry
What: One tracked file of an index with the stat fields the index recorded for it. Why: parse_index leaves the stat fields out, and the comparison with the file on disk needs them.

Enums§

CleanRefusalKind
What: Which kind of state kept a worktree from being proven clean. Why: Callers decide by kind, never by the words of the reason: the snapshot rung restores a worktree whose only trouble is an ordinary change, and refuses every state a restore cannot be proven to undo; the sentence for the person is chosen by kind.
StatVerdict
What: What the stat data of an index entry says about a file. Why: A file the data cannot vouch for (a racily clean entry, a stale stat) is not the same as a file that certainly changed: Git settles the first by content, so a caller that can compare content takes the two apart.

Functions§

check_clean
Cleanliness controls stay out of the release executable. What: Check that the worktree at root, whose Git directory is git_dir and whose shared directory is common_dir, is clean; return what its HEAD names, or the reason it cannot be proven clean. Why: The caller turns a refusal into a quiet fall to the next rung (or to Git’s own removal) and logs the reason.
check_clean_tracked
What: The checks of check_clean that read no untracked file: no operation in progress, an index equal to the tree of HEAD, and every tracked file with the size, times and inode its index entry recorded. Why: A caller that copies the whole worktree, untracked files included (the conversion of a worktree into a subvolume), needs a quiet and unmodified tracked state but has no reason to refuse for an untracked file, and needs no Git process.
check_clean_tracked_by_content
What: check_clean_tracked that settles an entry the stat data cannot vouch for by comparing the file with the committed blob in process, under the configuration and attribute locations of environment. Why: The conversion copies the whole worktree and rewrites the index afterwards, and an entry it could not prove keeps its old stat data, so Git hashes it at the first status; the snapshot and clone rungs install the index they proved and use the stat-only check.
dirty_source
What: For a worktree check_clean refused with the ordinary change why, what HEAD names, or the refusal that a restore cannot undo when the index holds one anywhere. Why: The first refusal hides the rest: a staged edit can come before a submodule or a skip-worktree entry, and only a look at every entry tells a change a reset undoes from a state it does not.
head_commit
What: The commit HEAD resolves to, read from the plain ref files. Why: An unusual ref storage answers “unknown”, which declines the shortcut rather than guessing.
metadata_differs_from_entry
What: The reason a file whose metadata is metadata differs from its index entry, or nothing when the two agree. Why: Callers that rely on the stat data alone (the snapshot and clone rungs) treat a file the data cannot vouch for like a file that changed.
metadata_verdict
What: What the stat data of the entry says about a file whose metadata is metadata. Why: The comparison takes the metadata of an inode already in hand, so a caller that holds a descriptor judges the file it holds, not whatever the path names a moment later. Type and executable bit come before the time checks: they differ whatever the content is.
stat_fields_beneath
What: The stat fields of the tracked file path below the held directory root, found through handles, or nothing. Why: The index of a snapshot takes the stat fields of the snapshot’s own files; reading them by a path with several components would follow a link substituted below the root.
stored_stats
What: The tracked files of the index paired with their recorded stat fields, or nothing when the layout is not plain. Why: The comparison with lstat needs the fields parse_index leaves out.
tree_differs_from_index
What: The first reason a tracked file of root differs from its index entry, or nothing when every file agrees. Why: After a snapshot the same comparison runs against the snapshot’s own files, so a source that changed while the snapshot was taken is caught on the copy. The files are reached below a held root with no link followed, so a directory replaced by a link is not read through.
tree_differs_from_index_beneath
What: The first reason a tracked file below the held directory root differs from its index entry, or nothing when every file agrees; each file is looked at below handles opened without following a link. Why: A snapshot is checked against the index it will carry; a path walk through a link inside the snapshot would compare a file outside it, so every directory on the way must be a real one on the snapshot’s device.
tree_fields_beneath
What: Judge every tracked file below the held directory root against its index entry and return the stat fields of each, in entry order, in one walk. Why: The snapshot’s index takes the stat fields of the snapshot’s own files, and the snapshot is proven equal to the source’s index by the same stat data; the same statx serves both, so the files are looked at once, and the fields are the ones the verdict was given on.