gitgitignoreinotifyinotifywait

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


I'm trying to listen file changes in a folder except .gitignore to trigger rebuild.

It seems like using inotifywait with --exclude option is the right way to do. Does anyone know a good way to convert .gitignore to regex such that inotifywait --exclude can accept correctly?


Solution

  • Here is a full example that watches for changes on non-gitignored files in the current directory, and runs ./build if any file changes.

    One important thing is that .git/ is not .gitignored, so we check and ignore it as well.

    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.

    If you are a Vim user, you will also want the configs:

    set backupcopy=no
    set noswapfile
    set nowritebackup
    

    In Vim 8.1, set backupcopy=no prevents events of type:

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

    The annoying 4913 is mentioned at:

    (TODO minimize with vim -u NONE) prevents the creation of .swp files: How to prevent vim from creating (and leaving) temporary files?

    Ideally we would also have --event moved_to,create but Vim generates 3 events per :w in that case, even though I tried to turn off all temporary files (TODO minimize example config with vim -u NONE):

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

    You could also consider to check if the file is git tracked to automatically include the .git: How to tell if a file is git tracked (by shell exit code)? but this approach is better as it uses the new files that you are testing even before they start being tracked.