diff --git a/CHANGELOG.md b/CHANGELOG.md index a1ca0eaac2..8058692476 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * crash when opening submodule ([#2895](https://github.com/gitui-org/gitui/issues/2895)) * when staging the last file in a directory, the first item after the directory is no longer skipped [[@Tillerino](https://github.com/Tillerino)] ([#2748](https://github.com/gitui-org/gitui/issues/2748)) * index-out-of-bounds panic when unstaging lines near the end of a diff ([#2953](https://github.com/gitui-org/gitui/issues/2953)) +* `--watcher` panic when a watched repo contains a directory owned by another user; live-refresh is now disabled instead of crashing ([#2900](https://github.com/gitui-org/gitui/issues/2900)) ## [0.28.1] - 2026-03-21 diff --git a/src/watcher.rs b/src/watcher.rs index ea30c7f135..9c4007caee 100644 --- a/src/watcher.rs +++ b/src/watcher.rs @@ -73,10 +73,38 @@ fn create_watcher( let mut bouncer = new_debouncer(timeout, tx).expect("Watch create error"); - bouncer + + match bouncer .watcher() .watch(Path::new(&workdir), RecursiveMode::Recursive) - .expect("Watch error"); + { + Ok(()) => std::mem::forget(bouncer), + Err(e) => { + // e.g. a subdirectory owned by another user can make the + // recursive watch fail with `PermissionDenied`. Live + // updates are disabled in that case, but gitui should + // still start up normally instead of crashing (#2900). + log::error!( + "failed to watch '{workdir}' for changes, live-refresh disabled: {e}" + ); + } + } +} - std::mem::forget(bouncer); +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_create_watcher_does_not_panic_on_watch_error() { + // a path that cannot be watched (e.g. because it does not + // exist, or - as in #2900 - because a subdirectory is owned + // by another user) must not crash gitui. + let (tx, _rx) = std::sync::mpsc::channel(); + create_watcher( + Duration::from_millis(100), + tx, + "/nonexistent/gitui-watcher-test-path", + ); + } }