feat(ignore): auto-load .stglobalignore as shared folder ignore patterns#10742
feat(ignore): auto-load .stglobalignore as shared folder ignore patterns#10742grantstephens wants to merge 1 commit into
Conversation
97f0968 to
ecbb1a7
Compare
When a folder is loaded, patterns from a .stglobalignore file in the folder root are automatically appended after the local .stignore patterns. Because local patterns are evaluated first, .stignore can override global patterns (e.g. a !.git/config negation beats a .git/** ignore in .stglobalignore). Unlike .stignore, .stglobalignore is not listed as an internal file, so Syncthing syncs it between devices like any other file. This means shared ignore patterns only need to be written once and are propagated automatically when the folder syncs to a new host — without any manual setup on each device. Change detection is handled automatically: .stglobalignore is registered with the ChangeDetector during parse, so any modification triggers a pattern reload on the next scan. Closes syncthing#7311 Related: syncthing#10208, syncthing#2353 Signed-off-by: Grant Stephens <grant@stephens.co.za>
ecbb1a7 to
d99aec4
Compare
Adds description and versionadded note for the new .stglobalignore file, which is synced between devices and automatically loaded alongside .stignore. Related: syncthing/syncthing#10742 Closes syncthing/syncthing#7311 Signed-off-by: Grant Stephens <grant@stephens.co.za>
|
How can the user control the ordering of ignore patterns? If there are global patterns for a selective sync: And the user applies the same principle locally: Then it's not obvious that the global patterns are effectively dead. With the current solution (explicit Another pain point I see is that the user cannot control what ignores are applied locally. Any other device can push ignore patterns to them and it's not even possible to get around them. This type of not being in charge of your own Syncthing instance goes against Syncthing's current philosophy. So from my side, clear NAK. The workaround if you don't want to remember adding the include for every new folder already exists. Put that line in the folder defaults configuration. |
Purpose
Implements automatic loading of a
.stglobalignorefile from the folder root, appending its patterns after the local.stignorepatterns.This addresses a long-standing pain point: when a folder syncs to a new host,
.stignoreis not synced (by design), so users must manually recreate their ignore patterns on every new device. The common workaround is to put a#include .stglobalignoreline in each.stignore, but that still requires per-device setup.With this change:
.stglobalignorein the folder root.stglobalignoresyncs between devices like any normal file (it is not in theIsInternallist)Precedence: Local
.stignorepatterns are evaluated first, so they can override global ones. A negation in.stignoreoverrides an ignore in.stglobalignore, and vice versa.Change detection:
.stglobalignoreis registered with theChangeDetectorduring load, so modifications trigger a reload on the next scan — identical to how#includefiles are tracked.Missing file: If
.stglobalignoredoes not exist the folder loads normally with no error.Closes #7311
Related: #10208, #2353
Implementation notes
The global file loading lives entirely in
Load(), keepingparseLocked()as a pure "parse this reader → apply state" function. A newapplyPatterns()helper was extracted to hold the hash-comparison and state-setting logic, used by both paths.Two named constants are introduced:
IgnoreFile = ".stignore"(exported — callers inmodel.goetc. can migrate over time)globalIgnoreFile = ".stglobalignore"(unexported, single definition)Testing
Four new tests in
lib/ignore/ignore_test.go:TestGlobalIgnore/LocalNegationBeatsGlobalIgnore— global ignores.git/**, local negates.git/config; verifies local winsTestGlobalIgnore/LocalIgnoreBeatsGlobalNegation— local ignores a file that global tries to un-ignore; verifies local winsTestGlobalIgnoreMissing— no.stglobalignorepresent; verifies clean load with no errorTestGlobalIgnoreChangeDetection— modifies.stglobalignorewith a future modtime; verifies patterns reload correctlyRun with:
Screenshots
No GUI changes.
Documentation
Docs PR: syncthing/docs#1016
Authorship
Note: this PR was developed with AI assistance (Claude). The implementation was designed, reviewed, and is understood by me as the submitter. I am responsible for its correctness and accept the DCO accordingly.