inotify:除了 .gitignore 中的文件外,还可以观察文件变化吗?

inotify: Watch files changes except for files in .gitignore?

我正在尝试侦听除 .gitignore 以外的文件夹中的文件更改以触发重建。

似乎使用带有 --exclude 选项的 inotifywait 是正确的方法。有谁知道将 .gitignore 转换为正则表达式以便 inotifywait --exclude 可以正确接受的好方法?

不要试图提前告诉 inotifywait,最好通过 git check-ignore -nv --stdin 运行 修改路径。花更多时间在 gitignore 文档上,你会明白为什么,这些模式来自多个来源,它们是上下文相关的,它们只是阻止自动跟踪的东西,它们不会阻止你专门跟踪文件。

这是一个完整的示例,它监视当前目录中未git忽略的文件的更改,并在任何文件更改时运行./build

一件重要的事情是 .git/ 不是 .gitignored,所以我们也检查并忽略它。

inotifywait --event close_write --monitor --recursive . |
  while read -r directory events filename; do
    echo "directory events filename: \"${directory}\" \"${events}\" \"${filename}\""
    if ! echo "$directory" | grep -Eq '^\.\/\.git' &&
       ! git check-ignore --non-matching --verbose "${directory}/${filename}" >/dev/null 2>&1
    then
      echo 'will build'
      ./build
    fi
  done

GitHub upstream.

如果您是 Vim 用户,您还需要以下配置:

set backupcopy=no
set noswapfile
set nowritebackup

在 Vim 8.1 中,set backupcopy=no 阻止以下类型的事件:

directory events filename: "./" "CLOSE_WRITE,CLOSE" "4913"

令人讨厌的 4913 提到于:

(TODO minimize with vim -u NONE) 阻止创建 .swp 个文件:How to prevent vim from creating (and leaving) temporary files?

理想情况下我们也会有 --event moved_to,create 但 Vim 在这种情况下每个 :w 生成 3 个事件,即使我试图关闭所有临时文件(TODO 最小化示例配置vim -u NONE):

directory events filename: "./" "MOVED_TO" "README.adoc~"
directory events filename: "./" "CREATE" "README.adoc"
directory events filename: "./" "CLOSE_WRITE,CLOSE" "README.adoc"

您还可以考虑检查文件是否被 git 跟踪以自动包含 .git: How to tell if a file is git tracked (by shell exit code)? 但这种方法更好,因为它使用您正在使用的新文件甚至在他们开始被跟踪之前就进行测试。