SyncFolder — Desktop User Guide

Using Glob Patterns for Folder and File Filters

SyncFolder lets you control exactly which folders and files are processed during a synchronisation task by writing glob patterns in the filter fields of each task. This chapter explains how filters work, the supported glob syntax, and practical examples to get you started quickly.

How Filters Work in SyncFolder

Every task location has a root folder. When SyncFolder runs a task it walks the entire directory tree starting from that root. Filters are evaluated at each level of the walk to decide whether a folder or file should be included in — or excluded from — the synchronisation.

3 separate filter lists are available per location:

Filter listDefault behaviourEffect when a pattern matches
Folder exclusion filters No folders excluded The matched folder and its entire subtree are skipped — SyncFolder will not descend into it.
File exclusion filters No files excluded Matched files are skipped. Exclusion always takes priority over the inclusion list.
File inclusion filters All files included (must be explicitly enabled) When enabled and one or more patterns are defined, only files that match at least one pattern are processed — provided they are not also matched by an exclusion filter.
When the list is empty the app includes all files except files that are exluded.
Folder exclusion is evaluated before file filters. If a folder is excluded, none of its files are ever considered, regardless of any inclusion patterns.

File filter evaluation order

For every file that is encountered, SyncFolder applies the following logic in order:

Inclusion listExclusion listMatches inclusionMatches exclusionResult
EmptyEmpty✅ Included
EmptyHas patternsNo✅ Included
EmptyHas patternsYes❌ Excluded
Has patternsEmptyYes✅ Included
Has patternsEmptyNo❌ Excluded
Has patternsHas patternsYesNo✅ Included
Has patternsHas patternsNoNo❌ Excluded (no inclusion match)
Has patternsHas patternsYesYes❌ Excluded (exclusion wins)
Has patternsHas patternsNoYes❌ Excluded
Exclusion always wins. There is no way to override an exclusion pattern from the inclusion list. If a file matches both lists it will always be excluded.

Pattern Scope: Root-Relative vs. Any-Depth

A pattern can target a specific location in the tree, or it can match an item regardless of where it appears in the hierarchy. The leading characters of the pattern determine the scope.

PatternScopeExample
Bare name, with optional leading / (no leading **/) Root-relative — matches only directly under the root of the location build (or /build) — excludes a folder named build only when it sits directly under the root.
**/name Any-depth — matches the item at any level of the tree **/obj — excludes every folder named obj, wherever it appears.
Path with separators, with optional leading / (no leading **/) Root-relative sub-path — anchored to the root services/logs (or /services/logs) — excludes a logs folder inside a services folder at the root.
Path with separators and leading **/ Any depth — matches the path at any level of the tree **/services/logs — excludes any logs folder that is inside a services folder wherever it appears.
Important difference from .gitignore. Developers familiar with Git will expect a bare name like bin to match at any depth. In SyncFolder, bin matches only at the root. Use **/bin to match at any depth. This is the most common source of filter mistakes.

Glob Syntax Reference

SyncFolder supports the following glob tokens:

TokenMeaningExample patternMatches
* Any sequence of characters, not including a path separator *.tmp report.tmp, cache.tmp
** Any sequence of characters, including path separators (zero or more path segments) **/logs logs, src/logs, a/b/c/logs
? Exactly one character (not a separator) file?.txt file1.txt, fileA.txt
[abc] One character from the set [Dd]ebug Debug, debug
[a-z] One character in the range chapter[0-9] chapter1, chapter9
[!abc] One character not in the set [!.]hidden Any name ending in hidden whose first char is not a dot
{a,b} Alternation — matches any of the comma-separated alternatives *.{jpg,jpeg,png} photo.jpg, photo.jpeg, photo.png
Path separators inside a pattern must use the forward slash / regardless of the operating system. Backslashes are treated as escape characters and may produce unexpected results.

Folder Exclusion Filter Examples

Excluding well-known build and tooling folders

.NET / C# project
# Root-relative — skips bin and obj at root only
bin
/bin
obj
# Any-depth — skips bin and obj everywhere (monorepo)
**/bin
**/obj
# Root-relative — IDE and test output
.vs
TestResults
Node.js / JavaScript project
# Any-depth — node_modules can appear in sub-packages
**/node_modules
# Root-relative — build output at root
.next
dist
.cache
.turbo
Python project
# Any-depth — appear throughout the tree
**/__pycache__
**/*.egg-info
# Root-relative
.venv
venv
.mypy_cache
.pytest_cache
General version control & IDE
# Root-relative — these belong at root
.git
.svn
.hg
.idea
.vscode

Excluding folders by name pattern

# Exclude every folder whose name starts with a dot at root (hidden folders)
.*

# Exclude hidden folders at any depth
**/.*

# Exclude all folders named "temp" or "tmp" at any depth (case-insensitive)
**/[Tt]emp
**/[Tt]mp

# Exclude all numbered release folders directly under root
release[0-9]*

Excluding folders at a specific sub-path

# Exclude the "logs" folder inside "services" at root
services/logs

# Exclude a "snapshots" folder inside any direct child of root
*/snapshots

File Exclusion and Inclusion Filter Examples

File exclusion and inclusion patterns use the same glob syntax. They are configured in two separate lists in the task location settings. Remember that exclusion always takes priority — a file matching both lists will be excluded.

Exclusion list: excluding files by extension

# Skip compiled and intermediate output files
*.obj
*.pdb
*.ilk
*.suo
*.user

# Skip common log and temporary files
*.log
*.tmp
*.bak
*~

Exclusion list: excluding files by name pattern

# Skip all hidden files (names starting with a dot)
.*

# Skip desktop.ini and Thumbs.db anywhere in the tree
**/desktop.ini
**/Thumbs.db

# Skip numbered backup copies such as "report(1).docx"
*([0-9]).{docx,xlsx,pptx}

Using the inclusion list to restrict which files are processed

When the inclusion list is empty, all files that pass the exclusion list are processed. Add patterns to the inclusion list when you want to process only specific file types, regardless of what else is present in the folder tree.

— Inclusion list —
# Process only C# source and project files
**/*.cs
**/*.csproj
**/*.sln
**/*.xaml
A common pattern is to use the inclusion list to whitelist the file types you care about (e.g. source and config files), and use the exclusion list to trim away any files in those types that should still be skipped (e.g. *.designer.cs).

Combining exclusion and inclusion lists

— Exclusion list —
*.designer.cs          # Skip auto-generated designer files
*.g.cs                 # Skip source-generated files

— Inclusion list —
**/*.cs               # Process all C# files …
**/*.xaml             # … and all XAML files

Combining extensions with alternation

# Exclude all image files in one pattern
*.{bmp,gif,ico,jpg,jpeg,png,tif,tiff,webp}

# Exclude all Visual Studio generated files
*.{user,suo,cache,ncb,aps}

Best Practices

  • Prefer folder exclusions over file exclusions for large subtrees. Excluding a folder stops all traversal into it immediately, which is far more efficient than letting SyncFolder walk thousands of files only to exclude them one by one.
  • Use **/name for tooling folders in monorepos. Build output folders such as bin, obj, and node_modules can appear at multiple levels. A bare name like bin only excludes at the root — use **/bin to catch them everywhere.
  • Use bare names for project-specific root folders. Folders such as .vs, publish, or AppPackages are meaningful only at the root of the location. A bare name is sufficient and avoids accidentally excluding a same-named subfolder deeper in the tree.
  • Be aware of the difference from .gitignore. In .gitignore a bare name matches at any depth. In SyncFolder it matches only at the root. This is the most frequent source of filter mistakes when copying patterns from a .gitignore file.
  • Use the inclusion list to whitelist file types, not to override exclusions. Exclusion always wins. Use the inclusion list to define which file types are in scope, then use the exclusion list to trim specific files within those types.
  • Avoid overly broad patterns like **/* in exclusion lists. Such patterns exclude everything and are almost never what you intend. Be as specific as the situation requires.
  • Test new filters on a small folder copy first. Run a preview sync against a subset of your data before applying a new pattern to a large production location.
  • Use alternation {} to consolidate related extensions. Grouping related extensions into one pattern (e.g. *.{jpg,jpeg,png}) makes the filter list shorter and easier to audit.
  • Comment your filter lists. Lines beginning with # are treated as comments. Use them to explain why a pattern exists, especially for non-obvious exclusions.
  • Keep a shared filter template for each project type. Maintaining one canonical filter set per technology stack (WinUI, .NET, Node, etc.) and reusing it across task locations reduces configuration drift and review overhead.
  • Revisit filters after major toolchain upgrades. Build tools frequently change the names or locations of their output folders. After upgrading an SDK or package manager, verify that your existing exclusion patterns still cover the new output paths.

Related topics: Configuring Task Locations · Running a Preview Sync · Conflict Resolution Rules
updated

Last modified: april 15, 2026