Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions changelog.d/workspace-watcher-agrees-with-scans.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
- A watched mount passes over what its `ignore` list covers, as a sync without a path does. The watcher handed chokidar the list as strings, which chokidar 4 compares with whole absolute paths, so no pattern matched, and every covered file the watcher saw change was taken in. A copy taken in that way stays as it was stored to every pass that names no path: a later change on disk isn't taken in, and its deletion is taken in where a walk lists its directory, as for anything a complete listing lacks. A copy beneath a directory the list covers stays, deleted on disk or not, the directory itself included, and so does one an `ls`, `glob` or `grep` reaches by its own path, or a sync naming a directory above it reaches by its walk.
- A mount nested inside another is passed over by the outer one as another mount's directory, in every pass, named or not, and by its watcher. The outer mount's ignore list gained the nested mount's path as written, which matched nothing for a mount more than one level down (`a/b`), so the outer mount took its files in as its own, and which matched the name at any depth for one directly beneath (`c`), so the outer mount also passed over unrelated entries with that name, such as `sub/c`. Now the outer mount's `ignore` list is left as configured, and the nested mount's directory is passed over as itself, counted under `passedOver` as "another mount's directory": the outer mount stops taking the nested mount's files, and takes files that only share its name. A sync that names that directory, or a path beneath it, with `/` between its segments, takes nothing in, and says so under `ignored`, where it took the nested mount's files in, since a named sync sets aside the `ignore` entries covering what it names (#276). That holds where an `ignore` entry covers a directory above the nested mount too. Files an outer mount stored from a nested one before, as `main`'s `a/b` mistake let it, stay in its branch's history and are listed with whose they are, but are passed over by its syncs, counted under `passedOver` and not under `incomplete`, and left out of its materialize and of `status`'s pending changes, conflicts and workspace deletions (its `fileCount` counts the tree as it stands).
- **The outer mount now refuses a nested mount's paths, reads included.** `read`, `read_image`, `write`, `edit`, `delete`, `readBinary`, `writeBinary`, `readBinaryFromDisk` and `readFileFromDisk` refuse a path in another mount's directory nested in the mount they name, judged where the path lands once its `.` and `..` segments and repeated separators are resolved, and the message names the mount that holds it and the path to use there; `readFileFromDisk`'s error code for it is `other_mount`, and `resolveAbsolutePath` returns null for such a path. A generated file the host registers at such a path is the same file whichever mount names it, and either reads it from its generator. `grep` returns none of the outer mount's copy of such a path; `ls` and `glob` list it with a note naming the mount that holds it and the path to use; a listing or `grep` naming a path there names them in its region, and a sync naming one in its note under `ignored`. A push of the outer mount, forced or not, skips such a path; a `materialize` that names one lists it under `skipped`, naming the mount that holds it, as a sync that names it does under `ignored`. A mount configured with a trailing separator no longer refuses its own root as traversal, and one configured with a relative path no longer refuses every path, generated files included, so the path the message names works. Before, a write through the outer mount, and any copy its store held there, went to disk at its next materialize over the nested mount's file wherever disk still agreed with the outer mount's evidence, and a forced one, as an undo or a branch switch makes, whatever disk held; and a read through the outer mount returned its own copy. A mount whose name only begins with two dots, such as `..cache`, now counts as nested.
- Three families of editors' swap and backup file names are passed over by a sync without a path, a listing and the watcher: `.name.swp` and `.name.swx` as the whole name (vim), and names ending in `~` (backups) or in `.subl…tmp` (Sublime Text's saves in progress), matched by `^\..+\.sw[px]$`, `~$` and `\.subl.*\.tmp$`. A directory with such a name is passed over with what lies beneath it. A sync counts one it doesn't track under `passedOver` as "an editor's swap or backup file", and reports one it tracks under `incomplete`. Naming one in a sync still syncs it, and lists it under `ignored`. Before, the watcher hid these names through chokidar's `atomic` option while a sync took them in, and that option tested the whole path, unanchored, so it also hid names such as `report.v2.swp`, and under a directory with a dot in its name, such as `~/.local/…`, every name ending in `.swp` or `.swx`, `notes.swp` included. The watcher no longer uses that option. An editor's save by rename reaches the workspace as a change to the file when the new copy is on disk by the time the watcher's batch is taken in, after its debounce. A copy still being written then is taken in as it stands and again whole once written, and one saved after a longer pause than the debounce is taken in as a deletion and then a creation. A copy already stored stays as it was to every pass that names no path, until its deletion is taken in, and a materialize treats it as any file the workspace holds, as it does a path the `ignore` list covers: it writes the workspace's copy while disk has what they last agreed on, as after a branch switch to history that holds it, and leaves a change disk made alone, as a conflict, unless forced.
- An `ls`, `glob` or `grep` that names a directory the mount passes over, such as one a bare-name `ignore` entry covers (`node_modules`) or one with an editor's name (`drafts~`), or a path beneath one, now takes nothing in there, and names the region under `incomplete`, adding that a sync that names the path takes in what's there, editors' files aside, as it still does. A copy the workspace stored there is listed, unobserved. Before, it listed such a directory and started tracking what it found; one a path entry such as `cache/**` covers listed nothing, and named nothing. A file tool names the path it acts on, as a sync naming it does: `read`, `edit`, `delete` and `readBinary` take in a file there that the workspace doesn't hold, as before, and the pass `write`, `edit`, `delete` and `writeBinary` make first, to settle a pending change on their path, observes it too.
Loading
Loading