From 25384d3f3b034df09c5deb1b08d424a4cce9dcc9 Mon Sep 17 00:00:00 2001 From: puttaalu Date: Sun, 18 Oct 2026 22:19:09 +0200 Subject: [PATCH] Rebuild on file renames so deletes take effect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The watcher only reacted to Create/Write/Remove. A /manage delete moves the image and sidecar into content/.trash/, which on Linux arrives as a Rename (inotify IN_MOVED_FROM), not a Remove — so the watcher never fired and the delete left the published site unchanged (uploads worked because they Create and Write). Watch Rename too, which also covers removing a photo with a manual mv. The delete handler still triggers its own immediate rebuild; this makes the watcher path agree with it. --- watcher.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/watcher.go b/watcher.go index 4ec8efb..800187f 100644 --- a/watcher.go +++ b/watcher.go @@ -30,6 +30,12 @@ func NewWatcher(dir string, g *Generator) (*Watcher, error) { // Watch blocks, watching for changes and triggering rebuilds. // Rapid events (e.g. scp writing an image then its sidecar) are debounced // with a 500 ms window so only one rebuild fires per logical upload. +// +// Rename is watched alongside Create/Write/Remove: moving a photo out of the +// content directory — which is exactly what a /manage delete does when it +// sends files to content/.trash/ — arrives as a Rename (inotify IN_MOVED_FROM) +// on Linux, not a Remove, so without it a delete (or a manual mv) would leave +// the site unrebuilt. func (w *Watcher) Watch() { var timer *time.Timer rebuild := func() { @@ -47,7 +53,8 @@ func (w *Watcher) Watch() { if !isRelevant(event.Name) { continue } - if event.Has(fsnotify.Create) || event.Has(fsnotify.Write) || event.Has(fsnotify.Remove) { + if event.Has(fsnotify.Create) || event.Has(fsnotify.Write) || + event.Has(fsnotify.Remove) || event.Has(fsnotify.Rename) { if timer != nil { timer.Stop() }