Subject: bug#21435: 25.0.50; file-notify has problems after renames

From: Eli Zaretskii <[email-masked]>
Date: Thu, 10 Sep 2015 18:45:13 +0300

> From: Michael Albinus <[email-masked]>
> Cc: [email-masked],  [email-masked]
> Date: Thu, 10 Sep 2015 13:09:36 +0200
> 
> file-notify-handle-event' is called directly by the low-level library,
> w32notify here. It sends the events
> 
> (file-notify (100286608 removed "xxx"))
> (file-notify (100286608 added "xxx"))
> (file-notify (100286560 removed "xxx"))

Yes.

> The first two events are raised by the file name handler for d:/usr/eli/data.
> Maybe "xxx" did exist already in that directory?

No, it didn't.  I don't know why w32 sends this strange notification,
but the fact is it does.  (That doesn't happen when moving a
directory, btw, only when moving files.)

> The last event comes from from file name handler for d:/tmp - this looks
> OK. Well, the order of the events is not as expected (the third event
> shall be the first one), but we never gave a promise for a canonical order.
> 
> I would say, that w32notify does not send the renamed-from and
> renamed-to events, as expected. Maybe they are sent only in case of
> renaming a file in the same directory?

Yes, that's exactly what happens.  Which IMO is entirely reasonable,
since each watch watches only a single directory.  That inotify has
some kind of "global" perspective on such rename events is a bonus,
but we cannot expect that.

This, of course, breaks the basic assumption of the design intended to
provide this feature:

> Two days ago (commit dbdc459a48091f5953faf14bcaaa7e6d37fbf024), I've
> changed filenotify.el to fire 2 events `renamed' in case the directories
> of the source and target are different. This was triggered by a user
> report, that he wants to have auto-revert-mode for two different
> directories under dired control. So the event is sent for the two
> different handlers activated by the respective *-add-watch calls.

The design expects 2 'move'/'renamed' events, but that's not
guaranteed, and doesn't happen on w32.  If we want to conflate
'removed' followed by 'added' into a rename across directories, we
will need changes in filenotify.el, and will risk false positives,
because it could really be a deletion followed by a creation of a file
by the same name.

However, if all we want is to make sure the destination directory gets
a notification (so it could auto-revert), then this already happens on
MS-Windows (see the 'created' event above), and therefore nothing
should be done on Windows to support the user request above.

Therefore, I submit that a better solution would be to make inotify
emulate what w32notify does, i.e. produce a synthetic 'added' event in
the destination directory when we get a 'moved-to' event that
specifies a destination directory different from the source.

Finally, two more comments about this:

 . I wish such changes were discussed, and the various alternatives
   examined, before the code is changed

 . I'm not sure this kind of non-trivial logic is something that
   belongs to filenotify.el; it could well have a better place in
   auto-revert.el instead, as that is the level where the logic is
   needed and understood, or even in the Dired-specific function that
   auto-reverts a directory