syncthing / syncthing/syncthing

ignore-pattern generator hook

Open
#10,796 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement needs-triage
Dominant language
Go
Stars
88.8k
Forks
5.5k
Avg merge
2d 10h
Merged PRs (30d)
5

Description

Feature description

Proposal

An optional hook that acts purely as an ignore-pattern generator. At scan time, Syncthing invokes a user-configured command, passes it the folder root, and reads ignore patterns from the command's stdout. That output is parsed by the existing ignore engine and merged with static .stignore rules. The hook decides nothing directly. Its only effect is to emit the same patterns a user could have written by hand.

Because the hook runs as part of Syncthing's own scan, it also removes the double traversal: the patterns are produced during the pass Syncthing already performs, rather than by a separate walk beforehand.

Example use: a script that prints one rooted pattern for each directory containing a .git entry, so working directories are excluded automatically as repositories come and go.

Safety model

A hook introduces risk only if it lets an actor run code they could not already run. This design removes every such path:

  • Local configuration only. The hook command lives in a dedicated on-disk configuration field that the REST API and GUI cannot read or write. Setting it requires filesystem write access to Syncthing's configuration, which is already equivalent to running arbitrary code as that user. The hook therefore grants no new capability.
  • Not network-reachable. Because the API and GUI cannot set it, an exposed GUI, a browser-based attack against the local API, or a shared account with API-only access cannot introduce a command.
  • Not peer-supplied. The hook command is not part of folder metadata and cannot arrive through a synced file or an #include directive. A remote peer can send patterns to be matched, never code to be run.
  • Disabled by default. Enabling the feature requires an explicit opt-in, such as a startup flag or environment variable, in addition to the configuration field.

The result is that the hook is exactly as trusted as the user's own shell, and no more. It cannot modify or delete files. Its entire influence is the set of patterns it prints.

Invocation contract

  • Invoked once per folder per scan, not once per file, to bound cost.
  • Folder root is passed by argument or environment variable. Patterns are read from stdout, one per line, and parsed identically to .stignore.
  • Execution is bounded by a timeout.
  • On non-zero exit or timeout, Syncthing aborts the scan and reports the error, so a hook failure can never silently widen what gets synced. The scan retries on the next cycle.
Problem or use case

Excluding version-control working directories, and similar build or dependency trees, requires listing each one by path in .stignore. There is no way to compute the exclusion set from the actual contents of a folder, so the ignore file drifts out of date as directories are added, moved, or removed.

Alternatives or workarounds

Users work around this with external scripts that regenerate .stignore. Besides duplicating effort, this is wasteful: the script must walk the entire tree to find the directories to exclude, and then Syncthing walks the same tree again during its scan. The filesystem is traversed twice for what is logically one pass. The external walk also races against live scans, so the ignore file can be stale exactly when Syncthing reads it.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing Syncthing's existing scan path and ignore engine, which the proposal says already parses .stignore rules. Determine where a per-folder hook could run and how timeout, failure, and retry behavior fit there; done means generated stdout patterns merge with static rules without a second traversal or silent scan widening.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
distributed-systems
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.