Add .protonignore and .gitignore support for keeping files out of sync - #2
Open
Musiker15 wants to merge 2 commits into
Open
Add .protonignore and .gitignore support for keeping files out of sync#2Musiker15 wants to merge 2 commits into
Musiker15 wants to merge 2 commits into
Conversation
Adds two ignore files. A .protonignore on the root of a sync folder, which applies to the whole sync root, and a .gitignore in any directory, which applies to that directory and everything below it, the same way Git applies it. Precedence is shallower .gitignore, then deeper .gitignore, then .protonignore, so a negated pattern in .protonignore can bring back something a repository .gitignore excludes. The pattern syntax is the gitignore one, with two Windows adjustments. Matching is case insensitive, and both slash and backslash are accepted as separators, so the backslash only escapes a leading # or !. A rule keeps an item out of synchronization, it never takes one out of the cloud. The adapter reports an item it stops seeing as a deletion, and the sync engine would propagate that to the opposite replica. So a rule matching an item that is already indexed is skipped and logged, and only items the adapter has not seen yet are held back. For the same reason the rules are evaluated on the local replica only, the remote adapter gets NullIgnoreRuleProvider. ItemExclusionFilter now returns a decision instead of a bool, so the update detection can tell a built-in exclusion apart from a user rule. The six call sites in the enumeration and event log steps are unchanged, SuccessStep resolves the decision internally.
The rule that keeps already indexed items in synchronization was too coarse. It only asked whether the adapter knows the node, so anything that entered an ignored name by being renamed was pinned into synchronization for good. That is how it behaves in practice for almost everything created through Explorer, because Explorer does not create anything under its final name. A new folder is Neuer Ordner first and a new file is New Text Document.txt first. The placeholder name matches no rule, the item gets indexed and uploaded, and by the time it carries the ignored name it counts as already indexed. Verified in a VM: a coverage2 folder and an info.bak file both ended up in the cloud although the matching .gitignore entries were in place well before they were created, and the activity list showed the Neuer Ordner placeholder right next to them. The two situations are told apart by the name. Equal names mean only the rule set changed, and the item is kept, which is what protects existing data. Different names mean a rename, and that is treated like every other exclusion, so the copy under the old name goes away. The built-in exclusions have always worked that way for renames into temporary file names, so this also removes an inconsistency between built-in and user defined rules. PROTONIGNORE.md now documents both directions instead of claiming that a rule never removes anything.
Musiker15
force-pushed
the
pr/ignore-rules
branch
from
August 10, 2026 16:44
03a9005 to
785dfb1
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this adds
Two ignore files, so that files can be kept out of synchronization the way .gitignore keeps them out of a repository.
.protonignore on the root of a sync folder applies to that whole sync root. .gitignore in any directory applies to that directory and everything below it, exactly where Git would apply it. Precedence is shallower .gitignore, then deeper .gitignore, then .protonignore, so a negated pattern in .protonignore can bring back something a repository .gitignore excludes.
The pattern syntax is the gitignore one with two Windows adjustments: matching is case insensitive, and both separators are accepted, so the backslash only escapes a leading # or !.
Where it hooks in
ItemExclusionFilter already existed for temporary files and special folders. It now returns a decision instead of a bool, so update detection can tell a built-in exclusion apart from a user rule. All six call sites in the enumeration and event log steps are unchanged, SuccessStep resolves the decision internally.
Rules are evaluated on the local replica only. The remote adapter gets NullIgnoreRuleProvider, because excluding a remote item would report it as gone and delete the local counterpart.
The part worth reviewing
An adapter that stops reporting an item is indistinguishable from a user deleting it, so a filter in this position is a deletion primitive. Two situations have to be told apart:
They are told apart by comparing the indexed name with the incoming name.
The distinction is not cosmetic. Without it the feature barely works, because Explorer does not create anything under its final name. A new folder is "Neuer Ordner" first and a new file is "New Text Document.txt" first, so the item gets indexed under the placeholder name, then renamed into the ignored name, and is then pinned into synchronization for good. I hit exactly that in testing before adding the name comparison.
Verification
The matcher was checked against 35 cases covering anchors, negation, directory-only patterns, **, character classes, nested rule set chains and precedence.
Then a full run in a Windows VM against a test account with an empty sync folder. Eleven of eleven fixture cases behaved as specified, nested .gitignore files were confirmed to be loaded and applied to the right subtree, and both branches of the safety rule were confirmed in the log, for a file and for a directory.
PROTONIGNORE.md documents the syntax, the precedence and both directions of the safety behaviour.
Notes
I am aware the README says contributions are not accepted. Opening this anyway so that it is visible to anyone who wants the feature.
Unrelated to this change, the repository does not build from a clean clone. Proton.Cryptography and Proton.Drive.Sdk are not on nuget.org and no feed is configured, and src/Proton.Drive.Update/Releases/ is missing because [Rr]eleases/ in .gitignore matches it. See #1 and my comment there. My fork works around both, written up in BUILDING.md: https://github.com/Musiker15/windows-drive/blob/feature/ignore-rules/BUILDING.md