Watchexec 1.18.0

Release notes

This is the first release built on top of Watchexec library 2.0. Any change in behaviour other than listed below is a bug.

  • Verbose mode is now more configurable, with -v, -vv… up to -vvvv printing increasingly more logs. Note that -v already prints a lot more logs than in previous releases, and that the log format has changed. Additionally, the RUST_LOG environment variable can be set for even finer-grained logging.
  • --changes-only was renamed to --print-events, and its output changed. The former option persists as an alias for compatibility but will be removed eventually.
  • --no-ignore was renamed to --no-project-ignore for clarity. The former option persists as an alias for compatibility but will be removed eventually.
  • When the command ends with a non-0 exit code, or by a signal, or a Windows exception, a message is printed (e.g. [[Command exited with 63]]) (#37)
  • The --notify / -N option now works properly, and is therefore out of experimental.
  • Finding the "project origin" now considers other VCSs and many software development tooling conventions.
  • Ignore file loading has been improved, with support for:
    • global VCS ignores (e.g. ~/.gitignore, ~/.bazaar/ignore) (#58)
    • global Git excludes (i.e. as configured in git config core.excludesFile)
    • local project git excludes (i.e. .git/info/exclude)
    • more VCS ignore files (for Mercurial, Darcs, Fossil, Bazaar) (nb gitignore syntax is assumed)
    • a watchexec-specific global ignore file in ~/.config/watchexec/ignore or as system-appropriate
    • any files listed in the new WATCHEXEC_IGNORE_FILES environment variable (format is as for the system PATH variable)
    • contextual ignores: git ignores won't be loaded for a Mercurial project, for example.
    • correct ignore file parsing, notably around folder patterns.
  • The environment variables set on the command have a number of minor changes:
    • paths are absolute
    • WATCHEXEC_COMMON_PATH is always set, with the common prefix of all paths
    • WATCHEXEC_OTHERWISE_CHANGED_PATH is new, for event kinds not covered by the other five (CREATED, META_CHANGED, REMOVED, RENAMED, WRITTEN)
    • within each envvar, paths are sorted (with binary ordering).
  • Permission and other errors encountered when watching files are now reported with the concerned file path, when available. (#149)
  • Basic Pijul support was added.
  • Some errors are now not fatal: they are reported to STDERR but won't cause a crash.
  • Mimalloc is used for musl builds, which may improve performance and reduce memory use. This is only done on musl because its default allocator is so terrible. Non-musl builds use the system allocator.

Note that this release is not coincidental with the stable release of the library 2.0, which is still "in preview."

New experimental filter engine

Set WATCHEXEC_FILTERER=tagged to opt into a new filter engine. This will disable the -e / --exts and -i / --ignore options and change the -f / --filter option to accept a "tagged filter" instead.

Documentation is available at:

For example, this set of filters:


would only allow file creation events from JSON files in data/ except those starting with test-.

There are 8 "tags" that can be matched upon, including path, kind (of the event: creates, modifies, metadata, etc), type (of the path that was changed: file, folder, link, etc). There is a variety of operators: glob (*= and *!), exact (== and !=), sets (:= and :!), and regex (~= and ~!). The shorthand = operator resolves to the "most useful" operator for the tag being matched (currently *= for path, kind, and exit, := otherwise). This provides a lot more power and flexibility, but does make filtering less intuitive — ideas are welcome on improvements.

The tagged filterer also solves the current filterer's main confusing issue: folder filtering. path=folder/ and path!*folder/ will do the expected thing, instead of requiring obscure forms like **/folder/**.

Using the --filter-file / -F option, one or more "tagged filter files" can be loaded, with every filter on a new line. Blank lines and lines starting with # are ignored. Like for ignore files, the WATCHEXEC_FILTER_FILES envvar is also consulted, and the ~/.config/watchexec/filter global filter file applies if present (or in system-relevant location). There is no default project-local filter file.

This mode is experimental: it is not to be considered stable in any way. Using it will print a warning message when watchexec starts. The aim is to have it become good enough so it can be the default in a future breaking release (but not 2.0, which will instead focus on other long-standing issues which aren't as earth-shattering as this), or to use its ideas to improve the existing implementation, whichever ends up better for everyone!


This release comes with special thanks to Radon Rosborough, supporting me via Ko-fi.


OS Arch Variant Download
Linux AArch64 glibc DEB (4.9 MB)
RPM (5.3 MB)
XZ (4.8 MB)
musl DEB (5 MB)
RPM (5.5 MB)
XZ (5 MB)
ARMv7 HF glibc DEB (5 MB)
RPM (5.5 MB)
XZ (5 MB)
x86 musl DEB (7.6 MB)
RPM (7.7 MB)
XZ (7.6 MB)
x86-64 glibc DEB (7.7 MB)
RPM (7.8 MB)
XZ (7.6 MB)
musl DEB (7.5 MB)
RPM (7.6 MB)
XZ (7.5 MB)
Windows x86-64 MSVC Zip (2.1 MB)
macOS AArch64 XZ (1.1 MB)
x86-64 XZ (1.2 MB)

View release on GitHub.


BLAKE3 checksums Automated signature (key) Félix’s signature (key)
SHA512 checksums Automated signature (key) Félix’s signature (key)

version released on 2022-01-18 | this page built on 2022-02-19 at 03:29 | generator v0.0.2 | json metadata