nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: fsnotify/fsnotify
Pull request #610 (2024-04-03 02:54:42)

Fix behavior of WatchList for Windows
#609 


Patch:
diff --git a/backend_windows.go b/backend_windows.go
index 0a60d0b..e82c8a1 100644
--- a/backend_windows.go
+++ b/backend_windows.go
@@ -329,7 +329,13 @@ func (w *Watcher) WatchList() []string {
 	entries := make([]string, 0, len(w.watches))
 	for _, entry := range w.watches {
 		for _, watchEntry := range entry {
-			entries = append(entries, watchEntry.path)
+			for name := range watchEntry.names {
+				entries = append(entries, filepath.Join(watchEntry.path, name))
+			}
+			// the directory itself is being watched
+			if watchEntry.mask != 0 {
+				entries = append(entries, watchEntry.path)
+			}
 		}
 	}
 


Test patch:
diff --git a/fsnotify_test.go b/fsnotify_test.go
index 760d022..17b9822 100644
--- a/fsnotify_test.go
+++ b/fsnotify_test.go
@@ -1551,11 +1551,6 @@ func TestWatchStress(t *testing.T) {
 }
 
 func TestWatchList(t *testing.T) {
-	if runtime.GOOS == "windows" {
-		// TODO: probably should I guess...
-		t.Skip("WatchList has always been broken on Windows and I don't feel like fixing it")
-	}
-
 	t.Parallel()
 
 	tmp := t.TempDir()
Repository: fsnotify/fsnotify
Pull request #620 (2024-04-25 13:56:35)

inotify: don't send event for IN_DELETE_SELF when also watching the parent
This would result in two events being sent.


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e439ed0..9c4f885 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,10 +15,13 @@ Unreleased
 
 - kqueue: set O_CLOEXEC to prevent passing file descriptors to children ([#617])
 
+- inotify: don't send event for IN_DELETE_SELF when also watching the parent ([#620])
+
 [#590]: https://github.com/fsnotify/fsnotify/pull/590
 [#610]: https://github.com/fsnotify/fsnotify/pull/610
 [#617]: https://github.com/fsnotify/fsnotify/pull/617
 [#619]: https://github.com/fsnotify/fsnotify/pull/619
+[#620]: https://github.com/fsnotify/fsnotify/pull/620
 
 1.7.0 - 2023-10-22
 ------------------
diff --git a/backend_inotify.go b/backend_inotify.go
index 66eb5d1..379431c 100644
--- a/backend_inotify.go
+++ b/backend_inotify.go
@@ -565,16 +565,24 @@ func (w *Watcher) readEvents() {
 				}
 			}
 
-			event := w.newEvent(name, mask)
+			skip := mask&unix.IN_IGNORED != 0
 
-			// Send the events that are not ignored on the events channel
-			if mask&unix.IN_IGNORED == 0 {
-				if !w.sendEvent(event) {
+			/// Skip if we're watching both this path and the parent; the parent
+			/// will already send a delete so no need to do it twice.
+			if !skip && mask&unix.IN_DELETE_SELF != 0 {
+				if _, ok := w.watches.path[filepath.Dir(watch.path)]; ok {
+					skip = true
+				}
+			}
+
+			/// Send the events that are not ignored on the events channel
+			if !skip {
+				if !w.sendEvent(w.newEvent(name, mask)) {
 					return
 				}
 			}
 
-			// Move to the next event in the buffer
+			/// Move to the next event in the buffer
 			offset += unix.SizeofInotifyEvent + nameLen
 		}
 	}


Test patch:
diff --git a/fsnotify_test.go b/fsnotify_test.go
index 873a904..a341f3c 100644
--- a/fsnotify_test.go
+++ b/fsnotify_test.go
@@ -720,6 +720,41 @@ func TestWatchRemove(t *testing.T) {
 			write /dir2/subdir
 			write /dir2/subdir/file
 		`},
+
+		{"remove while also watching parent", func(t *testing.T, w *Watcher, tmp string) {
+			// TODO: kind of a mess on Windows; sends something along the lines
+			// of:
+			//
+			//   create    /abc
+			//   write     /abc
+			//   write     /abc/def
+			//   write     /abc/def
+			//   remove    /abc/def
+			//   write     /abc
+			//   remove    /abc
+			//   remove    /abc
+			//
+			// But sometimes there's one or two more or less.
+			if runtime.GOOS == "windows" {
+				t.Skip("flaky")
+			}
+			addWatch(t, w, tmp)
+			mkdirAll(t, tmp, "/abc/def/ghi")
+			addWatch(t, w, tmp, "/abc")
+			rmAll(t, tmp, "/abc")
+		}, `
+			create    /abc
+			remove    /abc/def
+			remove    /abc
+
+			# TODO: no remove events?
+			dragonfly:
+				create    /abc
+			# TODO: no event for /abc/def?
+			fen:
+				create    /abc
+				remove    /abc
+		`},
 	}
 
 	for _, tt := range tests {