Sync Exclusions
A mounted project normally syncs everything: any file you write shows up for every other machine mounting it. That's the right default, but not everything belongs on the hub - node_modules/, build output, local caches. Swarmfile reads .gitignore the same way git does and treats a match the same way sync does: the file stays exactly where you put it and works normally on your machine, it just never uploads.
This is on by default, the same way a .gitignore in a fresh git repo is just expected to work.
.gitignore vs .swarmfileignore#
If your project is already a git repo, its .gitignore is enough - Swarmfile reads the same file, with the same syntax, and nothing extra to maintain. .swarmfileignore exists for two other cases: a project with no git repo at all (a CAD or media project versioned only by Swarmfile itself), and excludes that are only about sync, not about git - a local scratch folder or a cache directory you'd never want in a git commit either, but don't want to mix into a .gitignore that other tooling also reads. The two files use identical pattern syntax and combine additively: a directory can have both, and either one can exclude a path the other doesn't.
Nested rules, just like git#
Rules cascade the way git help gitignore describes: a .gitignore in a subdirectory is layered on top of the project root's, and if the two disagree, the deeper one wins - including a !pattern negation un-ignoring something a shallower rule excluded. .git/info/exclude and your global core.excludesFile are honored too, at the bottom of the precedence order: global excludes, then .git/info/exclude, then the project root's own .gitignore/.swarmfileignore, then anything closer to the file. Within one directory, a .swarmfileignore line is applied after that directory's .gitignore lines, so it can override a rule the .gitignore set for the same directory.
What a teammate actually sees#
An ignored file isn't deleted or blocked - it behaves exactly like an untracked file in git. You can create it, write to it, and read it back on the machine that made it, same as anything else on the mount. What changes is visibility to everyone else: the file never uploads, so it doesn't appear in ls, Explorer, Finder, or the web dashboard's Files view on any machine whose own ignore rules match it. It isn't hidden metadata with empty content - it's absent from the listing entirely, the same as a file that was simply never created there.
There's one exception worth knowing: opening the exact path directly (not browsing to it) still works, but only if the bytes are already sitting on that machine - because this machine wrote them, for instance. If they aren't there, Swarmfile won't fetch them from the hub just because you asked for the path by name; an ignored file is never fetched, only ever served from what's already local.
The web dashboard's Files view has a Show ignored files toggle for anyone who needs to see the unfiltered truth - an admin auditing what's actually sitting on the hub, or checking whether something is worth cleaning up (see below). With it off (the default), the dashboard matches whatever an ordinary mount would show you.
If a file was already synced before you ignored it#
Ignoring a path doesn't retroactively unsync it. A file that made it to the hub before your .gitignore rule existed - or one created by a teammate's machine that doesn't have the matching rule - keeps its existing hub-side content indefinitely. This is exactly how git treats a file you stop tracking with git rm --cached: the ignore rule stops future changes from syncing, it doesn't erase what's already there.
To actually remove that old content, run:
swarmfile ignore-clean
It scans your project (or a subtree, if you pass a path) for anything already on the hub that your current ignore rules would exclude, shows you exactly what it found before touching anything:
3 item(s) already on the hub match your ignore rules, totaling 340.0 MiB:
node_modules/ (directory)
dist/ (directory)
.env.local (file, 2.1 KiB)
This will remove them from the hub for everyone - recoverable from Trash for a while, not instant or permanent.
Proceed? [y/N]
and only deletes after you confirm (or pass --yes). Deletion goes through the same Trash system as any other delete, so it's recoverable, not instant or permanent - but it does remove that content for everyone, not just you. Be careful running this on a shared project if a teammate's machine might not have picked up the same .gitignore yet, or might be relying on something inside a directory you're about to clean up: ignore-clean only knows about your machine's current ignore rules, not anyone else's. It won't touch a path currently locked by someone else - the delete is refused, not silently skipped - but that only catches a file open for editing right now, not one a teammate's tooling reads without holding a lock.
macOS metadata files never sync#
On macOS, two kinds of file the system writes by itself stay on your machine without any ignore rule: AppleDouble ._name files (where macOS keeps a file's Finder tags, comments, and other extended attributes on the drive) and .DS_Store (Finder's per-folder view settings). They're meaningless to anyone else, and syncing them would put one extra hub entry beside nearly every file and folder a Mac user touches. They're hidden from listings on the machine that wrote them and never upload. This applies even with sync exclusion turned off, and no whitelist rule can override it.
Two limits keep it from touching anyone's real data. It only applies on macOS: on Windows or Linux, a ._x or .DS_Store you create came from an unzipped archive or an imported repo, so it syncs like any other file. It also only applies when the file is created: one already on the hub (synced before this rule, or from another machine) stays listed, readable, and synced.
Office owner files never sync#
Word, Excel, and PowerPoint write a small ~$name owner file beside a document while it's open - it records who has the document open, and the app deletes it when the document closes. Swarmfile keeps those files on the machine that wrote them and never syncs them, with no ignore rule: it applies even with sync exclusion turned off, and no whitelist rule can override it. Unlike the macOS files above, this applies on every platform Office runs on. It's also create-time only, the same as the macOS rule - an owner file that already reached the hub (synced before this rule, or by a teammate on an older build) stays listed and synced.
One thing this deliberately does not cover: Word's ~WRD####.tmp / ~WRL####.tmp save scratch files still sync. Word renames those over the document as part of saving, so keeping them local-only would strand the save; they normally disappear the moment a save completes. If a save fails or Word crashes, a leftover scratch file can show up as an ordinary project file until you delete it.
Windows Mark of the Web never syncs#
Windows tags a file you download with a Zone.Identifier alternate data stream, the "Mark of the Web": it records that this machine got the file from the internet, which is what makes Office open it in Protected View and Windows warn before running it. That is about how your machine got the file, not about the file, so Swarmfile keeps it on the machine that wrote it and never syncs it. Copying a downloaded file onto the drive works as usual, and the stream reads back on that machine, but your mark is never sent to a teammate. Other alternate data streams still sync. Like the rules above, this needs no ignore rule and nothing overrides it. Unlike them, it also covers marks already on the hub: one uploaded by an older build is never copied onto a machine that doesn't already have it. One a machine already picked up from the hub before updating stays there, though, and just stops syncing: Swarmfile can't tell it apart from that machine's own mark, and removing it would remove a security warning, so it errs toward keeping the warning.
Rules apply across the team, with one caveat#
Because .gitignore and .swarmfileignore are themselves ordinary synced files, everyone mounting the project ends up with the same exclusion rules once those files have synced to their machine - you don't need to hand-distribute them. The one moment this isn't instant: on a machine that just mounted the project and hasn't fetched anything yet, there's a brief window where a not-yet-fetched ignore file contributes no rules, so sync proceeds normally until it arrives in the background. This resolves itself within moments, not something to work around.
Checking whether a path is ignored#
If a file isn't showing up where you expect - or one you meant to exclude keeps syncing anyway - ask directly instead of guessing:
swarmfile check-ignore ./Projects/node_modules/pkg.js
ignored - excluded by node_modules ignore rules: `node_modules/`
For a path nothing excludes, it just says not ignored. The output names both which directory's rules made the call and the exact pattern that matched - useful when a nested .gitignore is overriding one closer to the project root, or a !negation is un-ignoring something you expected to stay hidden.
Turning it off#
Sync exclusion is on by default. Turn it off from the Desktop App's Settings panel (Sync-exclude .gitignore'd files), or set sync_ignore_enabled to false in that machine's config.json, or export SWARMFILE_SYNC_IGNORE_ENABLED=0. With it off, no path is ever hidden from listings, excluded from upload, or refused on read, no matter what any .gitignore says.
Flipping this switch - either direction - restarts the engine. It changes how the mount itself behaves, not something that can be swapped out from under it while it's running.
Example#
A typical .gitignore at a project's root:
node_modules/
.git/
dist/
*.log
With sync exclusion on, node_modules/ and dist/ build up locally as normal - npm install and your build both work exactly as they would on disk - but nothing under them ever uploads, and teammates never see those directories appear in their own mount.