Repository navigation
Conversation
Windows clients rejected every path an SSH host sent. The helper is Unix-only, so remote roots are /-rooted, but Path::is_absolute also wants a drive letter on Windows. Root discovery, the scan header and the picker now check remote paths with is_remote_absolute, which agrees with is_absolute on Unix. The volume picker test compared against the unresolved temporary path. Accepting a local root canonicalizes it, and the temporary directory is /var -> /private/var on macOS and an 8.3 short name on Windows runners. spawn_command and wait in remote.rs are only used by the Unix tests, so clippy -D warnings failed on Windows. Gate them on unix.
Path::has_root also accepts \x and C:\x on Windows, which name nothing on the Unix host the helper runs on. Check for a leading / instead.
serve also runs on Windows, and the round-trip tests there send native C:\ roots. Accept a path that is absolute on this platform or /-rooted; \x stays rejected.
The preview comes from the Unix helper's streaming walk. On Windows serve sends a finished tree with no preview, so the test's unwrap failed there. It was hidden on main because cargo test stops at the first failing test binary, which was the app's.
SSH hosts are Unix: the remote command, the embedded scanners and the delete script are POSIX shell and Linux tools. But remote paths were joined, split and compared with std::path, which follows the client. On a Windows client that joined /home/x and child into /home/x\child, so marks, the trail and the exported delete script named files that do not exist on the host, and a Unix name containing \ or : failed the whole scan. PathStyle (core) holds both rules: Native is std::path for local scans, Posix is /-separated for SSH hosts. path_of, mark lookup and display, crumbs, the trail, mark containment and the progress line now go through it. On Unix clients the two agree, so nothing changes there. Marks are keyed by exact path text, since PathBuf equality on Windows treats \ as a separator. The client refuses a Windows host by name, and checks the header's home and disk root as well as its root. The SSH CLI refuses a root that is not /-rooted. The round-trip tests that run the helper locally are Unix-only, since the local machine is the host; new hand-built streams and a window test cover a Unix host on every client.
huntharo
force-pushed
the
fix/remote-path-separators
branch
from
October 24, 2026 02:10
022f781 to
329e872
Compare
Four window tests built a local fixture, set app.remote, then looked up the fixture's own paths. On Windows those are C:\ paths, which a Unix host never sends and POSIX rules do not resolve. remote_view_over roots the scanned fixture at the temporary directory on Unix, keeping the nothing-deleted checks real, and at /srv/fixture on Windows.
These run disktree-scan on the test machine and read what it sends, so the machine is the host. Clients now refuse Windows hosts, so on Windows they failed with that refusal. The disconnect test reads no snapshot and still runs everywhere.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #114. Only the last commit (
ssh: treat remote paths as POSIX paths on every client) is new; the earlier four disappear from this diff once #114 merges.Problem
SSH hosts are Unix: the remote command, the embedded scanners and the delete script are POSIX
shand Linux tools. But the client joined, split and compared remote paths withstd::path, which follows the client's rules. On a Windows client:path_ofjoined/srv/dataandlogsinto/srv/data\logs. Marks, the trail, the agent prompt and the exported delete script then named files that don't exist on the host. With root/,realpathdecides whether the script deletes a file literally named\logs.\or:(common on Linux) was rejected, which failed the whole scan.PathBufequality on Windows treats\as a separator, so marks on/a/b\cand/a/b/ccollided.~shortening, breadcrumbs, the trail separator and the indexing line all split remote paths by Windows rules.Change
disktree_core::path_style::PathStyle:Nativeisstd::path, used for local scans.Posixis/-separated, used for SSH hosts. It provides join, parent, file name, ancestors, relative names, names and is-below. The app picks one fromremote.is_some(). On Unix clients the two agree, so local and Unix-client behaviour is unchanged.PathStyle:tree::path_of,marks::find/refresh/is_hidden/display_path,crumbs_for_path, breadcrumbs and crumb labels, mark containment (toggle_mark,marked_ancestor, the remote plan filter,marks_ancestor),short_name, the trail separator, and the indexing progress line.PathBufequality.platform: "windows"is refused by name, instead of being half-read with the wrong separator. The header'shomeanddisk_rootare now checked as POSIX-absolute, likeroot. The Windows-only rejection of\and:in names is gone, because those names are now joined correctly.disktree ssh HOST PATHrefuses aPATHthat doesn't start with/.PathStyle.Tests
path_styleunit tests for both styles:\and:in names, name boundaries (/srvvs/srvx), the root, trailing slashes, andC:\/\xnot being POSIX-absolute.remote.rsthat run on every client. One checks that names with\and:arrive whole. The other checks that a Windows host, and a non-POSIX home or volume, are refused.logs\old/a:b, checks crumbs, the mark, the trail and~display, and copies the delete script. On a Windows runner this is the case that used to break.cfg(unix), because that machine is the host. (Fix the macOS and Windows CI failures on main #114 already made the live preview dedup test Unix-only.)disktree-scanexecutable tests that read a snapshot or a discovery result arecfg(unix). The disconnect test reads neither and still runs everywhere./path (remote_view_over): the temp directory on Unix,/srv/fixtureon Windows.Verified locally on macOS:
cargo xtask lintandcargo xtask testpass, andcargo clippy -p disktree-core --all-targets --target x86_64-pc-windows-msvc -- -D warningsis clean. The app crate can't be cross-checked for Windows from macOS, so CI is the first run of these tests on a Windows client.Note for local runs: gpui-omarchy's theme watcher watches
$HOME. While other processes write there, app tests can abort with "Detected activity on thread notify-rs fsevents loop". Running withHOMEset to an empty directory avoids it. This is unrelated to this change.