v1.1.0
2026-09-18
v1.1.0 corrects the macOS requirements and fixes the paths where ghfs could hand a reader incomplete or wrong issue content.
Breaking Changes
macOS 26 and macFUSE 5.4.0 or later are now required
ghfs mounts through the macFUSE File System Extension, and macFUSE offers that extension only on macOS 26 or later. Earlier releases of ghfs documented “macOS 15.4 or later”, which was never correct. macOS 15 is no longer supported.
macFUSE 5.4.0 or later is also required. Earlier macFUSE releases duplicate directory entries and can lose the volume while ghfs is reading a file.
On macOS, install macFUSE first, enable the macFUSE File System Extension in System Settings > General > Login Items & Extensions > File System Extensions, and then install ghfs.
Linux and WSL 2 requirements are unchanged.
Bug Fixes
Directory listings were truncated, duplicated, or empty
On macOS, a directory with many entries stopped at 63 entries and the rest were
invisible. Listing the same directory twice within 500 ms returned nothing the second
time, and tree could see entries twice or see none at all. An agent that listed
.ghfs/ twice in a row could read it as holding no issues, with no error anywhere.
ghfs now resumes a listing from the offset it was given and no longer keeps a short-lived cache of directory entries. A directory returns all of its entries however many it holds, and repeated listings return the same result.
Reading an issue file could return content that was never in the file
With macFUSE 5.4.0, a zero-length read reply makes read(2) report that it read the
requested length while writing nothing into the caller’s buffer. The caller then uses
whatever its buffer already held, and the failure is invisible. Background sync can
shrink an issue while a reader is still working from the size reported earlier, which
is how ghfs reached that reply. On macFUSE 5.3.x and earlier, the same reply crashed
the File System Extension and took the volume with it.
ghfs now fixes an issue file’s content when the file is opened, so the reply is never zero-length.
Background sync skipped repositories whose issues were active
Polling decided whether a repository was active from the repository’s own update time, which does not change when an issue is updated. A repository whose issues were moving but whose repository record was old could be skipped entirely. Activity is now judged from the newest issue update, and a skip is recorded in the log.
A disabled File System Extension caused a restart loop
When the macFUSE File System Extension was not enabled, the daemon crashed while
mounting, the service manager restarted it, and the log grew without limit. The daemon
now records consecutive mount failures and stops retrying, and ghfs doctor reports the
reason and how to enable the extension.
There is no way to read the extension’s state before mounting, so the mount failure itself is what ghfs reports.
The daemon reported a successful mount that had failed
When volume registration failed, the daemon still logged FUSE mounted and kept
running. The mount point stayed an empty directory and nothing indicated an error. The
daemon now reads the mount table before and after mounting and treats the mount as
successful only when a new entry has appeared.
Checking for a leftover mount could hang
After the daemon ended abnormally, ghfs checked the mount point by reading the
directory. While a leftover macFUSE file system module holds that path, any read of it
never returns and cannot be interrupted, so the check itself hung. The daemon,
ghfs doctor, and the release tests now read the mount table instead. The daemon stops
before attempting to mount and prints the recovery steps.
Improvements
Daemon logs rotate
Running as a service, the daemon writes to ~/.ghfs/logs/daemon.log by default,
switches files at 10 MB, and keeps 3 generations. log_file, log_max_size, and
log_max_backups configure this. Started from a terminal, ghfs daemon start still
writes to stderr only.
ghfs doctor reports more
On macOS, ghfs doctor now reports whether macFUSE is installed and which version it
is, and lists recorded consecutive mount failures with their reasons.
install.sh checks the macOS and macFUSE versions
The installer now warns when the machine runs macOS earlier than 26, when macFUSE is older than 5.4.0, and when macFUSE is absent. It warns; it does not stop the installation.
Known Limitations
Recovering from an abnormal daemon exit takes a manual step (macOS)
When the daemon ends abnormally, the macFUSE file system module keeps holding the volume. ghfs cannot tell which module holds which volume, so it cannot clear this on its own.
- ghfs does not start again until the module is quit by hand
- quit it with
pkill -f io.macfuse.app.fsmodule.macfuse - this quits the module for every macFUSE volume on the machine, so unmount other macFUSE volumes first
- no reboot is needed
ghfs doctor and the daemon’s startup error both print these steps.
A listing split across calls can miss or repeat entries
A large directory is returned over several calls. If background sync changes the directory between calls, an entry can be missed, skipped, or returned twice. Issue counts change only at the polling interval, so a change has to land inside a short window for this to happen, and no occurrence has been observed. How the resume position should be anchored is not settled.
An issue that changes state can stay in open/ for up to 5 minutes (Linux)
On Linux the mount is set up with entry_timeout=300, matching the default five-minute
polling interval. After an issue is closed, its file can remain visible under open/
until that cache expires.
Supported Platforms
- macOS 26 or later, Apple Silicon, with macFUSE 5.4.0 or later
- Linux x86_64 / ARM64 with libfuse3
- Windows through WSL 2, using the Linux build
Installation
curl -fsSL https://ghfs.dev/install.sh | sh
An existing installation updates with ghfs update.