notify-rs / notify

🔭 Cross-platform filesystem notification library for Rust.
https://docs.rs/notify
2.77k stars 222 forks source link

【with tokio】After executing `git checkout .` command and then modifying the file, unable to get response to file changes #541

Open jiesia opened 1 year ago

jiesia commented 1 year ago

System details

What you did (as detailed as you can)

I am using notify and tokio to monitor file changes. During the process, I found a bug: after I executed git checkout . command in the monitored directory, notify could no longer respond to file changes.

Below is all my code

use std::fs;

use notify::{
    event::{CreateKind, DataChange, ModifyKind, RemoveKind, RenameMode},
    EventKind, RecommendedWatcher, RecursiveMode, Watcher,
};
use tokio::sync::mpsc::channel;

#[tokio::main]
async fn main() {
    let _ = tokio::spawn(async move { watch().await }).await;
}

async fn watch() {
    let (tx, mut rx) = channel(2);
    let mut watcher = RecommendedWatcher::new(
        move |res| {
            tx.blocking_send(res).unwrap();
        },
        Default::default(),
    )
    .unwrap();

    fs::read_dir("example").unwrap().for_each(|path| {
        let path = path.unwrap().path();
        if path.is_file() {
            watcher
                .watch(path.as_path(), RecursiveMode::NonRecursive)
                .unwrap();
        } else {
            let path_str = path.to_string_lossy();
            if path_str.contains(".git") {
                return;
            }
            watcher
                .watch(path.as_path(), RecursiveMode::Recursive)
                .unwrap();
        }
    });

    while let Some(res) = rx.recv().await {
        match res {
            Ok(event) => match event.kind {
                EventKind::Any => {}
                EventKind::Access(_) => {}
                EventKind::Create(CreateKind::File) => {
                    println!("\nwatch create file");
                }
                EventKind::Modify(ModifyKind::Data(DataChange::Any)) => {
                    println!("\nwatch modify data");
                }
                EventKind::Modify(ModifyKind::Name(RenameMode::Any)) => {
                    println!("\nwatch modify name");
                }
                EventKind::Remove(RemoveKind::Any) => {
                    println!("\nwatch remove any");
                }
                EventKind::Remove(_) => {
                    println!("\nwatch remove other");
                }
                _ => {}
            },
            Err(e) => {
                println!("watch error: {:?}", e);
            }
        }
    }
}

What you expected

I expect that after executing git checkout . command and then modifying the file, I can still monitor the file changes.

What happened

After I executed git checkout . command in the monitored directory, notify could no longer respond to file changes.