Skip to content

feat: open file paths SSH panes print, and upload saves back - #627

Open
leftos wants to merge 9 commits into
penso:mainfrom
leftos:feat/remote-file-links
Open

leftos wants to merge 9 commits into
penso:mainfrom
leftos:feat/remote-file-links

Conversation

@leftos

@leftos leftos commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Summary

A link-modifier click on a file path printed in a pane on an SSH device did nothing: local_link_at (window/file_links.rs) dropped every path on a remote pane, since this machine cannot open that host's files. On macOS and Linux clients such a path is now a link, and the click opens the host's file here.

  • Fetch and open. The click copies the file over the device's own noninteractive SSH trust into a per-launch cache folder (remote_files/cache.rs), one subfolder per window, and opens the copy under the same rule as a local path: a document opens in its default application, anything else opens the folder holding it. Files up to 64 MB; a folder, a larger file, or a missing one shows why nothing opened. Each window keeps its own copies, so a fetch in one window never replaces another's unsent edits, and a second click while a fetch runs starts nothing.
  • Windows and POSIX hosts. A drive or UNC path, or a Windows working directory for a relative path, picks Windows PowerShell 5.1+ through -EncodedCommand; anything else picks /bin/sh. Relative paths join the pane's cwd with the host's separator; ~ expands on the host. This builds on fix: make Windows drive paths in pane text clickable #610's drive-path reading.
  • Saves go back, with consent. The copy is watched off the UI thread, once a second, and a change counts once two runs agree. The first save asks: Upload, Upload future saves without asking, or Not now. Each upload carries the SHA-256 the host's file had when last synced; if it changed on the host, nothing is written and a dialog offers Keep both (notes.conflict.md beside it), Overwrite anyway, or Re-fetch. A failed Re-fetch offers the conflict again, and saving the copy back to its synced bytes drops the question and closes its dialog. A conflict dialog closed without an answer comes back when the path is clicked again, which still opens the copy. A fetch records the downloaded file's metadata before putting it in place, so a save made as the copy lands is still noticed. A repeat fetch that keeps edits moves the copy aside, hard-links the download into its place (which fails rather than replace a save that took the place), and puts the copy back unless its metadata proves it unsaved; the watch skips a copy a fetch is writing, and a conflict's Re-fetch holds the copy as a click's fetch does.
  • Host-side guards (herdr-client/src/remote_file*). A push writes a temp file beside the target and renames it over the target only when it holds exactly the expected byte count and the host's file still matches; symlinks and non-regular files are never replaced. File bytes travel only on stdin/stdout, and the untrusted path only as a quoted literal in the script.
  • An upload never widens who can read the file. On POSIX the push enters the target's folder once (cd -P), builds the copy in a private mktemp -d folder inside it (checked to be the SSH user's drwx------ folder there, every file in it made by mktemp), gives it the target's group and mode, and moves it over the target with mv -T/mv -h where mv takes one. It writes in place instead when the group cannot be kept with the same reach or an ACL shows (ls +, an ACL listed by macOS ls -lde, or getfacl -s), but only in a folder no one else can replace files in (owned by the SSH user or root, no ACL, and not writable by group or others unless sticky with the target the user's or root's); elsewhere it refuses: "Other users can replace files in that folder on the host, so it was not written in place; nothing was changed." An unwritable target is refused with its own exit code, and the user sees "Could not keep the file's access; nothing was changed." Keep both never writes in place and re-checks the new name just before the rename. The host needs id, ls and rmdir besides the tools it already used. Windows PowerShell 5.1 and 7 create the temp file with the target's DACL. Keep both gives the conflict copy the original file's access (RemoteFileAccess::Like).
  • herdr-gpui remote-files [list] reports the copies a window holds and their sync state, per the Command Line rule. It is read-only.
  • Hover never contacts the host: a remote path is underlined by its shape. Plugin link handlers keep the first claim. WSL and cloud panes are unchanged.
  • Windows clients too. Now that main runs SSH children on Windows (feat(windows): add and connect to saved SSH hosts on Windows #624, 1bf759b), the client builds the same ssh command for POSIX and Windows OpenSSH hosts on every OS, and SSH-pane path links are no longer limited to unix clients. A host file whose name Windows cannot store (<>:"/\|?*, a control character, a trailing dot or space, or a device name such as CON or com1.txt) gets a safe local copy name (a:b.txt becomes a_b.txt); dialogs and uploads keep the host's name and path. Without the rule, a:b.txt joined onto the cache folder is a drive-relative path outside it. On Windows the cache folder inherits the ACL of the user's state folder, as the app's other private files do.

Validation

Rebased onto main at 350e3e0. Run at 5945c64's tree on Windows 11 x86_64, and in WSL Ubuntu (Linux x86_64) on the same tree (earlier rounds' results below are marked with their commit):

  • check-commits (upstream/main..HEAD): ok
  • Windows just ci (local): format-check, check-file-size, check-sorted, both lint clippy passes, and cargo test --locked --workspace default and all features green (herdr-gpui 3793 and 3836, herdr-client 229, 0 failed). The un-gated window/file_links/tests remote and remote-save tests now run on Windows.
  • WSL at 5945c64's tree: clippy all features and no default features, and cargo test --workspace: passed, 0 failed (4241 passed). herdr-client remote_file --include-ignored: 41 passed.
  • Opt-in PowerShell remote_file tests on Windows (each script under powershell.exe 5.1 and pwsh 7): 23 passed.
  • remote_files/tests/windows_names.rs failed before the Windows name rule (a<b.txt kept; the copy path escaped as b.txt).
  • Not run: just lint-linux and just lint-windows.
  • Windows just test-mockup-wait: fails on Windows only, as in fix: make Windows drive paths in pane text clickable #610 (test_wait.py hands bash a Windows path). This PR touches nothing under .claude/.
  • WSL cargo clippy --locked --workspace --all-targets --all-features -- -D warnings and --no-default-features: ok (covers the cfg(unix) code Windows does not build)
  • WSL cargo test --locked --workspace, default features: herdr-gpui 4169 passed, 1 failed: orchestrator::tests::service::the_worker_shows_runs_another_application_writes timed out waiting for a snapshot under load. This PR touches no orchestrator code, and the test passes run alone. The all-features WSL run was not repeated after the rebase.
  • Greptile's second review: remote_files/tests/fetch_meta.rs (a save as the fetched copy lands is still asked about) and remote_files/tests/dismissed_conflict.rs (a click on a conflicted copy's path asks its closed question again, once) failed before their fixes.
  • macOS release build of leftos/patches (which carries this PR at 2d05c91) on Apple silicon, macOS 27.0.1: cargo build --locked --release -p herdr-gpui and just bundle succeeded.
  • macOS failure reproduced on Windows by pointing TMP at a junction (the /var -> /private/var case): a_script_opens_the_folder_holding_its_copy failed with the CI assertion before the fix and passes after, with and without the junction.
  • Each review fix has a test that failed first: in-flight fetches and per-fetch part files (remote_files/tests/fetches.rs), per-window copies, the Asking/Conflict + Reverted and failed Re-fetch rows in the step table, the stale-dialog close, and Keep both sending the original's access.
  • herdr-client remote_file in WSL with --include-ignored: 40 passed, including the ACL cases (setfacl on the target, a folder default ACL, the group rules for 0644/0640/0604/0664, Like sources that are links or folders, and the access-refusal exit code).
  • Opt-in PowerShell tests on Windows, local, under both powershell.exe 5.1 and pwsh 7.6, before the rebase (at 2d05c91): powershell_scripts_fetch_and_push_files, powershell_push_temporary_file_takes_the_targets_acl and powershell_push_kept_copy_takes_its_sources_acl passed.
  • Greptile's review of feat: open wrapped links, and paths with a ?query or #fragment #695 (56a5f78, 6a31f50), each fix with a test that failed first: WSL herdr-client remote_file 44 passed and posix_exec -- --ignored 2 passed (tool shims swap the target, the temp file and the work folder for links; a file planted before Keep both's rename; a folder ACL), remote_files/tests/fetch_swap.rs (saves in place, by temp-and-rename and through a handle at each step of the swap, the in-flight guard), and the backslash name tests. Then just ci on Windows (all but test-mockup-wait) and WSL clippy ×2 and cargo test --workspace default and all features at 6a31f50, all passed. On macOS 27.0.1 (Apple silicon) at 6a31f50, under its /bin/sh and BSD tools: herdr-client remote_file 44 passed and herdr-gpui remote_files 58 passed.

Screenshots

None attached yet: the first manual checks below ran on a MacBook, but no screenshots of the two dialogs or the underline on a remote pane were captured.

Known limitations

  • A file://<host>/path hyperlink naming the SSH host itself, as ls --hyperlink prints, still answers "on another host" (terminal/links.rs explicit_target). Printed paths and file:///path links fetch.
  • Copies with unuploaded edits are removed with the cache at quit without a warning.
  • On a macOS host, an inheritable folder ACL entry can read the temp file while the upload is written, since macOS ACLs are not masked by its 0600 mode. The final file is still right.
  • A failed Keep both leaves the copy as edited rather than offering the conflict again. On a Windows host, Keep both is refused when the original file is gone or its ACL cannot be read; a POSIX host writes a private copy instead.
  • Races that need another writer under the same SSH account remain: between the hash check and the rename, and a File.Replace failure partway (error 1177) can leave the Windows target in an unclear state.
  • A parent folder swapped before a push with Overwrite anyway still redirects the write, since the folder is anchored only once the push starts. The PowerShell push does not yet anchor against an NTFS junction swapped into the path.
  • On a host whose mv takes neither -T nor -h (older BusyBox), a link to a folder planted at the target in the moment before the rename makes mv move the copy into that folder; the target is unchanged.
  • Shared folders without a sticky bit (including 775 folders on hosts with per-user groups) no longer take in-place writes when the file's access cannot be kept on a renamed copy.

Manual QA

  • macOS, a Windows OpenSSH device: echo C:\dev\x\notes.md in a PowerShell pane, hold Cmd over it (solid underline), click: the copy opens in its default app. (MacBook Air, macOS 27.0.1, against a Windows 11 host running Herdr 0.9.4, with a notes.md:5 under the user's profile; leftos/patches build.)
  • Save the copy: the upload dialog appears; Upload, then check type C:\dev\x\notes.md on the host. (Same setup: the edit arrived on the host, line endings kept.)
  • Choose Upload future saves without asking on the next save: later saves upload with a toast.
  • Change the file on the host, then save the copy: the conflict dialog appears; try Keep both, Overwrite anyway, and Re-fetch.
  • Cmd+click a relative src\main.rs under the right cwd, a folder, and a file over 64 MB.
  • A Linux or macOS SSH device: ~/notes.md and a relative path open; an executable script opens its folder, and a push keeps its mode.
  • A Linux SSH device: a 0640 file of a group you belong to (not your primary group), and a file with a setfacl entry, both keep their group and ACL after an upload. Keep both on a 0600 .env gives a 0600 conflict copy.
  • Two windows on one SSH device: edit a copy in one and do not upload, then open the same path in the other. The first window's edits survive.
  • herdr-gpui remote-files lists the copies; quit, and the cache folder under ~/.local/state/herdr/gpui/remote-files/ is gone.
  • Windows client, a macOS or Linux SSH device: Ctrl+click ~/notes.md opens the copy; save and Upload; the file on the host changes. A host file named a:b.txt opens as a_b.txt, and its upload goes to a:b.txt.
  • Windows client, a Windows OpenSSH device: Ctrl+click C:\dev\x\notes.md opens the copy, and an upload lands.
  • A macOS SSH device: upload to a file in your home folder and to one with a chmod +a ACL entry; the first lands, the second is written in place, and no .notes.md.XXXXXX folder is left beside it.
  • A Linux SSH device: in a chmod 1777 folder and in a chmod 777 folder, upload to a file with a setfacl entry; the sticky folder takes the in-place write, the other refuses with "Other users can replace files in that folder on the host…" and the file is unchanged.

@leftos

leftos commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor Author

🤖 Posted by Claude Code on behalf of @leftos.

Local just ci checks at 9de0658, which merges main at 0ca50aa.

Windows 11 x86_64:

  • check-commits (upstream/main..HEAD): passed
  • format-check, check-file-size, check-sorted: passed
  • lint, all features and no default features: passed
  • test, default and all features: passed, 0 failed in all 46 test binaries (herdr-gpui 4286 and 4330). The first just ci run failed github::credential_manager::tests::a_secret_too_large_for_credential_manager_is_refused_and_keeps_the_old_one under load, in code this PR does not touch; it passes alone, and the full just test passed on the rerun.
  • test-mockup-wait: not rerun; it fails on every Windows machine until test: run the mockup wait tests on Windows #643 merges, and this PR touches nothing it covers.

Not run at 9de0658: WSL (Linux) and macOS. At 6946bc9, before the merge, WSL clippy (all features and no default features) and cargo test --workspace passed, and the macOS CI jobs ran the remote_file push tests.

The merge needed two fits to main: the remote-files command sits beside upstream's new security command in the control client, protocol and server, and the screen-reader page titles (1875ff6) name the Remote upload and Remote conflict pages.

The Windows native GUI jobs fail on main too (0ca50aa and later): the native_sidebar paint probe measures the child label at 179px or 127px against an expected 161px. This PR does not touch the sidebar, and its Linux and macOS jobs pass.

@greptile-apps

greptile-apps Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 4/5

[High impact] Adds file transfer over SSH with new remote file APIs.

Fix the download-completion race before merging so saved edits cannot silently go unnoticed.

Findings

  1. P1 A save goes unnoticed ▶
  2. P2 Conflict choices disappear ▶

Summary

Adds SSH file downloads, per-window cached copies, save-upload questions, conflict choices, and the read-only remote-files command.

  • SSH pane paths open a local copy fetched from the host.
  • Edits to fetched copies can be uploaded with consent and conflict choices.
  • The remote-files command lists copies and their sync states.

leftos acknowledges these deferred limits: unsent edits are deleted at quit without warning; host-named file:// links remain unsupported; macOS folder ACLs can expose temporary uploads; failed Keep both leaves the copy edited; Windows Keep both refuses an unavailable access source; and same-account host races and partial Windows replacement failures remain.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Click SSH file path] --> B[Download into window copy]
  B --> C[Open copy]
  C --> D[Watch saved changes]
  D --> E[Ask before upload]
  E --> F[Check host file hash]
  F -->|Matches| G[Upload saved bytes]
  F -->|Changed| H[Show conflict choices]
  H --> I[Keep both]
  H --> J[Overwrite anyway]
  H --> K[Re-fetch]
Loading

Reviews (2) · Last reviewed commit: "feat: list fetched SSH file copies with ..." · Reviewed by Greptile

Comment thread crates/herdr-gpui/src/remote_files.rs Outdated
Comment thread crates/herdr-gpui/src/remote_files.rs Outdated
Comment thread crates/herdr-client/src/remote_file/powershell.rs Outdated
Comment thread crates/herdr-gpui/src/remote_files/sync.rs Outdated
Comment thread crates/herdr-gpui/src/remote_files/sync.rs Outdated
@leftos
leftos force-pushed the feat/remote-file-links branch from b40727a to 2d05c91 Compare October 17, 2026 15:45
@leftos
leftos marked this pull request as ready for review October 17, 2026 17:06
@leftos
leftos requested a review from penso as a code owner October 17, 2026 17:06
@leftos
leftos force-pushed the feat/remote-file-links branch from 2d05c91 to 7d9b952 Compare October 17, 2026 17:13
Comment thread crates/herdr-gpui/src/remote_files.rs Outdated
Comment on lines +477 to +478
let synced_meta = std::fs::metadata(&local)
.and_then(|metadata| watch::Meta::of(&metadata))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 A save goes unnoticed

fetch_copy reads synced_meta from the destination after replacing it. If an editor saves between the rename and this read, the copy is recorded as Synced with the edit's metadata but the downloaded bytes' hash. The watcher then sees unchanged metadata and never asks to upload that save.

Capture the downloaded file's metadata from the part file before renaming it, so a later editor save remains detectable.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Posted by Claude Code on behalf of @leftos.

Fixed in 235791d: fetch_copy now reads the metadata from the whole part file before the rename. watch::Meta holds only mtime and length, and a rename keeps both, so the recorded metadata is the download's. A save made as the copy lands then differs from it and leads to the upload question. remote_files/tests/fetch_meta.rs saves to the copy right after the rename and failed before the change.

let orphans: Vec<Key> = self
.copies
.iter()
.filter(|(_, copy)| matches!(copy.state, SyncState::Asking { .. }))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Conflict choices disappear

Pressing Escape on the conflict dialog removes its only queued question but leaves the copy in Conflict. requeue_unanswered restores only upload questions, and clicking the path just reopens the edited copy. Users cannot choose Keep both, Overwrite anyway, or Re-fetch again without another save.

Keep a way to reopen dismissed conflicts, such as reopening their question when the path is clicked.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Posted by Claude Code on behalf of @leftos.

Fixed in 235791d: a click on the path of a copy in conflict still opens the copy, and now queues its conflict question again when it is neither waiting nor showing, so Keep both, Overwrite anyway, and Re-fetch come back after Escape. Two clicks queue it once. remote_files/tests/dismissed_conflict.rs covers both, and that a click on a copy not in conflict queues nothing.

@leftos
leftos force-pushed the feat/remote-file-links branch 2 times, most recently from d5c983d to ca502c5 Compare October 17, 2026 17:59
Add herdr_client::remote_file, which copies a file off an SSH host and
writes it back over the endpoint's noninteractive SSH trust, for the
upcoming remote file links in the GUI.

POSIX hosts run /bin/sh scripts; Windows OpenSSH hosts run Windows
PowerShell 5.1+ scripts through -EncodedCommand. The path travels quoted
in the script; file bytes travel only on stdout and stdin. Both shells
share one exit-code contract for missing, not-a-file, too-large,
symlink, no-hasher, and conflict refusals.

A push writes a private temporary file beside the target and renames it
over the target only while the host's file still matches the expected
SHA-256 (or is absent, or anything). An existing POSIX file keeps its
permission bits; a new one gets the login umask's default.

Tests run the POSIX scripts through a local /bin/sh and, opt-in, the
PowerShell scripts through a local powershell.exe and pwsh.
A link-modifier click on a path printed in a pane on an SSH device did
nothing, since this machine cannot open that host's paths. Such paths
are now links by their shape: a click fetches the file over the
device's SSH trust into a per-launch cache and opens the copy in the
system's application, or the folder holding it when it is not a known
document, under the same rule as local paths.

Windows OpenSSH hosts are recognised by a drive or UNC path, or a
Windows working directory for a relative path, and use PowerShell;
other hosts use /bin/sh. Relative paths join the pane's cwd with the
host's separator, and `~` is left for the host to expand.

Hover never contacts the host. Plugin link handlers keep the first
claim. WSL and cloud panes are unchanged, as are SSH panes on Windows
clients, which have no SSH children. The cache is removed at quit, and
folders left by earlier launches are swept on first use.
A copy fetched by clicking a path in an SSH pane is now watched for
saves. The first save asks whether to upload it: Upload, Upload future
saves without asking, or Not now. Later saves follow that answer, and
an automatic upload reports itself in a flash.

Every upload sends the hash the host's file had when it was last
synced. When the file changed on the host since then, nothing is
written and a dialog offers Keep both (uploads beside it as
name.conflict.ext), Overwrite anyway, or Re-fetch. Copies over 64 MB
are not uploaded.

The client's push now carries the exact byte count, and the host
refuses to replace its file with a temp file that holds fewer bytes,
so a dropped connection or cancelled upload leaves it unchanged. A
click that fetches a copy again keeps a save made while the fetch ran.
The host, shell, and path of a transfer travel as one RemoteFile.

Watching runs off the UI thread at most once a second; a change counts
once two runs agree on it, which lets an editor's atomic save settle.
Prompts wait for any open dialog instead of replacing it. Saving a copy
back to its synced bytes drops its question and closes its dialog, and
a failed Re-fetch offers the conflict again.

An upload never makes the file readable by anyone who could not read
it before. A POSIX host gives the temp file the target's group and
mode before the rename, and writes in place instead when the group
cannot be kept with the same reach or an ACL shows (`ls` `+` or `@`,
`getfacl`). Windows PowerShell 5.1 and 7 create the temp file with the
target's DACL. Keep both takes the original file's access. When access
cannot be kept and nothing can be written safely, the host exits with
its own code and the user is told so. A macOS host's inheritable
folder ACL can still read the temp file during the transfer.

Each window keeps its copies in its own cache folder, so a fetch in one
window never replaces another's unsent edits. A click while its file
is still being fetched starts no second fetch, and each fetch writes
its own part file.
`herdr-gpui remote-files [list]` reports the copies of SSH hosts'
files that link clicks fetched into the window, each with its host,
host path, local path, sync state, and whether its saves upload
without asking. It is read-only: uploads stay behind the app's dialog.
The reply fits the socket's message budget and counts what it omits,
as `notes list` does.

Document remote file links in the Herdr UI README, the transfer API in
the client README, the command in docs/cli.md, and the behaviour beside
open_files_in in the example config.
The overview said SSH needs "an installed POSIX Herdr", but a macOS
client connects to a Windows OpenSSH host running Herdr 0.9.4, and the
Files on SSH Hosts section already describes Windows hosts.
@leftos
leftos force-pushed the feat/remote-file-links branch from ca502c5 to 5945c64 Compare October 17, 2026 20:29
leftos added a commit to leftos/herdr-gpui that referenced this pull request Oct 17, 2026
# Conflicts:
#	crates/herdr-gpui/src/menu/chrome.rs
#	crates/herdr-gpui/src/menu/chrome/keys.rs
@penso penso added enhancement New feature or request P2 Normal backlog: enhancements, documentation, and less disruptive bugs labels Oct 19, 2026
Two fixes from review of the SSH file copies:

- A repeat fetch checked the copy for saves, then renamed the downloaded
  file over it, so a save landing between the two was overwritten and
  the copy marked synced. The copy now moves aside first, the download
  is hard-linked into its place, which fails rather than replace a save
  that took the place meanwhile, and the copy moved aside comes back
  unless its metadata proves it is the one last synced. A filesystem
  without hard links falls back to a rename. The watch run no longer
  probes a copy a fetch is writing, and a conflict's refetch now holds
  its copy in the in-flight set as a click's fetch does, so only one
  writer handles a copy at a time.
- A copy's file name was split at both separators for every host, so
  /srv/foo\bar.txt on a POSIX host was cached and shown as bar.txt. It
  is now split at the host shell's own separators, and on Windows the
  backslash becomes an underscore as the local naming rules intend.
The POSIX push script checked the target for a symbolic link, then
reopened it by name: for its temporary file, for chgrp and chmod, and
for the in-place write it falls back to when a file's ACL cannot be
kept. Another user who can rename entries in the folder could swap in
a link between the check and the write, so the upload landed in a
different file the SSH account can write.

The script now:

- enters the target's folder once with cd -P and names the target
  relative to it, so no later step re-resolves the folder's path;
- builds the copy in a private mktemp -d folder inside it, checked to
  be the SSH user's drwx------ folder within the anchored one, with
  every file in it created by mktemp, so nothing that already exists is
  opened or replaced, and moves it over the target with mv -T (GNU) or
  mv -h (BSD) where mv takes one;
- writes in place only in a folder no one else can replace files in
  (owned by the SSH user or root, no ACL, and not writable by group or
  others unless sticky with the target the user's or root's), and
  otherwise refuses with a new exit code, shown as "Other users can
  replace files in that folder on the host, so it was not written in
  place; nothing was changed.";
- never writes in place for Keep both, and re-checks that the new name
  is still free just before the rename.

A push now also needs id, ls and rmdir on the host.
A POSIX push renames a copy owned by the SSH user over the target, so a
target another account owned becomes the SSH user's. The copy kept the
target's mode, set-user-ID bit included: as root, pushing over another
account's 4755 file produced a root-owned setuid executable that runs as
root for everyone.

Keep the set-user-ID bit only when the copy's owner matches the file whose
access it keeps; an unreadable owner on either side drops it. Drop the
set-group-ID bit when chgrp fails and the copy keeps its own group. Sticky
stays: on a regular file it names no owner or group.
# Conflicts:
#	crates/herdr-gpui/src/cli/control/hosts.rs
#	crates/herdr-gpui/src/control/client/hosts.rs
#	crates/herdr-gpui/src/control/protocol/hosts.rs
#	crates/herdr-gpui/src/control/protocol/hosts/tests.rs
#	crates/herdr-gpui/src/control/server/hosts.rs
#	crates/herdr-gpui/src/control/server/hosts/tests.rs
#	crates/herdr-gpui/src/menu/chrome.rs
#	crates/herdr-gpui/src/menu/chrome/keys.rs

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request P2 Normal backlog: enhancements, documentation, and less disruptive bugs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants