diff --git a/NEWS b/NEWS index b6a64d4c3..145361c35 100644 --- a/NEWS +++ b/NEWS @@ -36,6 +36,8 @@ ver 0.20 (not yet released) * support libsystemd (instead of the older libsystemd-daemon) * database - proxy: add TCP keepalive option +* update + - apply .mpdignore matches to subdirectories ver 0.19.10 (2015/06/21) * input diff --git a/doc/user.xml b/doc/user.xml index a08a5aec0..8a37a7cce 100644 --- a/doc/user.xml +++ b/doc/user.xml @@ -1077,6 +1077,8 @@ database { To exclude a file from the update, create a file called .mpdignore in its parent directory. Each line of that file may contain a list of shell wildcards. + Matching files in the current directory and all subdirectories + are excluded. diff --git a/src/db/update/ExcludeList.cxx b/src/db/update/ExcludeList.cxx index 3b54d635e..b09f349ac 100644 --- a/src/db/update/ExcludeList.cxx +++ b/src/db/update/ExcludeList.cxx @@ -89,6 +89,12 @@ ExcludeList::Check(Path name_fs) const /* XXX include full path name in check */ #ifdef HAVE_CLASS_GLOB + if (parent != nullptr) { + if (parent->Check(name_fs)) { + return true; + } + } + for (const auto &i : patterns) if (i.Check(NarrowPath(name_fs).c_str())) return true; diff --git a/src/db/update/ExcludeList.hxx b/src/db/update/ExcludeList.hxx index de48bac99..4952d291a 100644 --- a/src/db/update/ExcludeList.hxx +++ b/src/db/update/ExcludeList.hxx @@ -36,15 +36,23 @@ class Path; class ExcludeList { + const ExcludeList *const parent; + #ifdef HAVE_CLASS_GLOB std::forward_list patterns; #endif public: + ExcludeList() + :parent(nullptr) {} + + ExcludeList(const ExcludeList &_parent) + :parent(&_parent) {} + gcc_pure bool IsEmpty() const { #ifdef HAVE_CLASS_GLOB - return patterns.empty(); + return ((parent == nullptr) || parent->IsEmpty()) && patterns.empty(); #else /* not implemented */ return true; diff --git a/src/db/update/Walk.cxx b/src/db/update/Walk.cxx index af039ee48..3e5654a3c 100644 --- a/src/db/update/Walk.cxx +++ b/src/db/update/Walk.cxx @@ -219,6 +219,7 @@ UpdateWalk::UpdateRegularFile(Directory &directory, void UpdateWalk::UpdateDirectoryChild(Directory &directory, + const ExcludeList &exclude_list, const char *name, const StorageFileInfo &info) { assert(strchr(name, '/') == nullptr); @@ -236,7 +237,7 @@ UpdateWalk::UpdateDirectoryChild(Directory &directory, assert(&directory == subdir->parent); - if (!UpdateDirectory(*subdir, info)) + if (!UpdateDirectory(*subdir, exclude_list, info)) editor.LockDeleteDirectory(subdir); } else { FormatDebug(update_domain, @@ -327,7 +328,9 @@ UpdateWalk::SkipSymlink(const Directory *directory, } bool -UpdateWalk::UpdateDirectory(Directory &directory, const StorageFileInfo &info) +UpdateWalk::UpdateDirectory(Directory &directory, + const ExcludeList &exclude_list, + const StorageFileInfo &info) { assert(info.IsDirectory()); @@ -340,17 +343,17 @@ UpdateWalk::UpdateDirectory(Directory &directory, const StorageFileInfo &info) return false; } - ExcludeList exclude_list; + ExcludeList child_exclude_list(exclude_list); { const auto exclude_path_fs = storage.MapChildFS(directory.GetPath(), ".mpdignore"); if (!exclude_path_fs.IsNull()) - exclude_list.LoadFile(exclude_path_fs); + child_exclude_list.LoadFile(exclude_path_fs); } - if (!exclude_list.IsEmpty()) - RemoveExcludedFromDirectory(directory, exclude_list); + if (!child_exclude_list.IsEmpty()) + RemoveExcludedFromDirectory(directory, child_exclude_list); PurgeDeletedFromDirectory(directory); @@ -361,7 +364,7 @@ UpdateWalk::UpdateDirectory(Directory &directory, const StorageFileInfo &info) { const auto name_fs = AllocatedPath::FromUTF8(name_utf8); - if (name_fs.IsNull() || exclude_list.Check(name_fs)) + if (name_fs.IsNull() || child_exclude_list.Check(name_fs)) continue; } @@ -376,7 +379,7 @@ UpdateWalk::UpdateDirectory(Directory &directory, const StorageFileInfo &info) continue; } - UpdateDirectoryChild(directory, name_utf8, info2); + UpdateDirectoryChild(directory, child_exclude_list, name_utf8, info2); } directory.mtime = info.mtime; @@ -468,7 +471,9 @@ UpdateWalk::UpdateUri(Directory &root, const char *uri) return; } - UpdateDirectoryChild(*parent, name, info); + ExcludeList exclude_list; + + UpdateDirectoryChild(*parent, exclude_list, name, info); } bool @@ -484,7 +489,9 @@ UpdateWalk::Walk(Directory &root, const char *path, bool discard) if (!GetInfo(storage, "", info)) return false; - UpdateDirectory(root, info); + ExcludeList exclude_list; + + UpdateDirectory(root, exclude_list, info); } return modified; diff --git a/src/db/update/Walk.hxx b/src/db/update/Walk.hxx index d9fe7c84c..99d54ef51 100644 --- a/src/db/update/Walk.hxx +++ b/src/db/update/Walk.hxx @@ -129,10 +129,12 @@ private: const char *name, const StorageFileInfo &info); void UpdateDirectoryChild(Directory &directory, + const ExcludeList &exclude_list, const char *name, const StorageFileInfo &info); bool UpdateDirectory(Directory &directory, + const ExcludeList &exclude_list, const StorageFileInfo &info); /**