Documentation
¶
Overview ¶
Package filestate measures a working tree without asking git anything.
It exists because git is not always there to ask. A repository with no commits has no HEAD to diff against, and a directory that was never a repository has nothing at all — and both are trees an agent can be working in. More of them will be: keeping track of what changed without a commit history is becoming its own problem, and a resident daemon watching a filesystem is the shape of the answer.
Where git can answer, it should: it knows what is ignored, and it knows how much of a modified file an edit actually touched. This does not. See Changes for what that costs and which way it errs.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrWalkBudget = errors.New("working tree exceeds the walk budget")
ErrWalkBudget reports that the tree holds more than the walk is willing to read.
Functions ¶
This section is empty.
Types ¶
type Entry ¶
type Entry struct {
// Hash is the SHA-256 of the file's contents, which is what makes a
// modification detectable without keeping the contents themselves.
Hash string
// Lines is how many lines the file has. Binary content reports none.
Lines int
}
Entry is one file's contribution to the state of a tree.
type Index ¶
Index is the state of a working tree: every file it holds, by path relative to the root, in slash form on every platform.
func Build ¶
Build walks the tree at root and hashes it.
Skipping is deliberately minimal: .git, and whatever the root .gitignore names in one of the three forms that cannot be misread — a bare name, a directory, or *.ext. Anything it is unsure about is walked and counted. That is the wrong way round for speed and the right way round for safety, since every file wrongly skipped makes the change look smaller than it is. The budgets above are what keep the honest version bounded.
func (Index) Changes ¶
Changes reports how far this index has moved from an earlier one. A nil before means there is no earlier state, so the whole tree is the change.
A modified file counts its whole length rather than the lines that actually changed. Without the earlier contents there is no way to know how much of it moved — only that it did — so it counts the most it could have, which over-measures a one-line edit in a long file as the whole file. That is the direction to be wrong in: an over-measured change is waited for, and an under-measured one is waved through. Where git can answer, it answers better; this is for the trees it cannot.
func (Index) Digest ¶
Digest reduces an index to one value, so two states of a tree can be compared without keeping either of them.
It is the git-free equivalent of a worktree fingerprint, for the same use: deciding whether a tree has moved while something else was looking away. Paths are folded in sorted order, since map iteration is random and a digest that depended on it would report every tree as changed.