Skip to main content

Hierarchical .dropboxignore for Dropbox on Windows (NTFS ADS) and Linux (xattrs)

Project description

dbxignore

Hierarchical .dropboxignore files for Dropbox. Drop a .dropboxignore into any folder under your Dropbox root and matching paths get the Dropbox ignore marker set automatically — no more node_modules/ cluttering your sync. Windows (NTFS alternate data streams) and Linux (user.* xattrs) supported.

Upgrading from v0.2.x

The project was renamed from dropboxignore to dbxignore in v0.3.0 (the old name collides with an unrelated 2019 PyPI project). Upgrade is a one-time manual step:

dropboxignore uninstall --purge   # on v0.2.x — removes state, logs, service
pip install dbxignore              # or: uv pip install dbxignore
dbxignore install                  # registers the new service under new names

Your .dropboxignore rule files carry over untouched — they're never modified by install/uninstall.

Requirements

  • Windows 10/11 (NTFS), or a modern Linux distro with a systemd user session
  • Dropbox desktop client installed
  • Python ≥ 3.11 with uv. The pre-built .exe (Windows only) is an alternative on Windows.

Install (Windows, from source)

uv tool install git+https://github.com/kiloscheffer/dbxignore
dbxignore install

dbxignore install registers a Task Scheduler entry that launches the daemon (pythonw -m dbxignore daemon) at every user logon.

Install (Linux)

Requires a systemd user session (standard on Ubuntu, Fedora, Debian, Arch, and most modern distros; WSL2 requires systemd=true in /etc/wsl.conf).

uv tool install git+https://github.com/kiloscheffer/dbxignore
dbxignore install                    # writes systemd user unit, enables it
systemctl --user status dbxignore.service

dbxignore install writes ~/.config/systemd/user/dbxignore.service and runs systemctl --user enable --now so the daemon starts at login.

For non-stock Dropbox installs, export DBXIGNORE_ROOT before running dbxignore install — the install step will read the variable from your shell environment and write a corresponding Environment="DBXIGNORE_ROOT=..." line into the generated unit's [Service] block. Without this, a shell-exported value won't reach the daemon when systemd launches it. If your Dropbox location ever changes, re-run dbxignore install after updating the export.

To uninstall:

dbxignore uninstall                  # disables unit, removes the file
dbxignore uninstall --purge          # clears markers, state files, logs, systemd drop-in

Notes:

  • Dropbox on Linux marks ignored paths with the xattr user.com.dropbox.ignored=1. Files on filesystems that don't support user.* xattrs (tmpfs without user_xattr, vfat, some FUSE mounts) are skipped with a WARNING in the daemon log — not a fatal error.
  • Several common operations strip xattrs silently: cp without -a, mv across filesystems, most archivers, vim's default save-via-rename. The watchdog plus hourly sweep re-apply markers automatically; no action needed.
  • Linux symlinks cannot carry user.* xattrs (kernel restriction). A symlink matched by a rule logs one WARNING per sweep and is skipped. Its target is not affected.

Install (.exe)

  1. Download dbxignore.exe and dbxignored.exe from the latest Release.
  2. Place both in a stable directory (e.g. %LOCALAPPDATA%\dbxignore\bin\) and add it to your PATH.
  3. Run dbxignore install.

Platform support

  • Windows 10 / 11 — first-class (v0.1). Uses NTFS Alternate Data Streams.
  • Linux — first-class (v0.2). Uses user.com.dropbox.ignored xattrs. Tested on Ubuntu 22.04 / 24.04. Requires a systemd user session.
  • macOS — planned for v0.3. Dropbox on macOS uses a different attribute mechanism (Apple File Provider) that requires runtime detection — not yet implemented.

.dropboxignore syntax

Full .gitignore syntax via pathspec. Matching is case-insensitive to accommodate NTFS. A file named .dropboxignore is never itself ignored — it needs to sync so your other machines see the same rules.

Example (put in a project root):

# everything javascripty
node_modules/

# Python
__pycache__/
.venv/
*.egg-info/

# Rust
target/

# build output
/dist/
/build/

# except this one specific artifact we want to share
!dist/release-notes.pdf

Commands

Command Purpose
dbxignore install / uninstall Register / remove the daemon with the platform's user-scoped service manager (Task Scheduler on Windows, systemd user unit on Linux). uninstall --purge also clears every existing marker, removes local dbxignore state (state.json, daemon.log*, the state directory), and on Linux removes any systemd drop-in directory. Any stray marker on a .dropboxignore file itself is logged at WARNING before being cleared.
dbxignore daemon Run the watcher + hourly sweep in the foreground. Usually invoked by Task Scheduler.
dbxignore apply [PATH] One-shot reconcile of the whole Dropbox (or a subtree).
dbxignore status Is the daemon running? Last sweep counts, last error.
dbxignore list [PATH] Print every path currently bearing the ignore marker.
dbxignore explain PATH Which .dropboxignore rule (if any) matches the path?

Behaviour

  • Source of truth. .dropboxignore files declare what is ignored. Removing a rule unignores the matching paths on the next reconcile. A path marked ignored via Dropbox's right-click menu but not matching any rule will be unignored.
  • Hybrid trigger. The daemon reacts to filesystem events in real time and runs an hourly safety-net sweep. If the daemon is offline, an initial sweep at the next start catches any drift.
  • Multi-root. Personal and Business Dropbox roots are discovered automatically from %APPDATA%\Dropbox\info.json (Windows) or ~/.dropbox/info.json (Linux).

Negations and Dropbox's ignore inheritance

Dropbox marks files and folders as ignored using xattrs. When a folder carries the ignore marker, Dropbox does not sync that folder or anything inside it — children inherit the ignored state regardless of whether they individually carry the marker. This matters for gitignore-style negation rules in your .dropboxignore.

If you write a negation whose target lives under a directory ignored by an earlier rule — the canonical case is build/ followed by !build/keep/ — the negation cannot take effect. Dropbox will ignore build/keep/ because build/ is ignored, no matter what xattr we put on the child. dbxignore detects this at the moment you save the .dropboxignore, logs a WARNING naming both rules, and drops the conflicted negation from the active rule set.

Negations that don't conflict with an ignored ancestor work normally. For example:

*.log
!important.log

Here nothing marks a parent directory as ignored (*.log matches files, not dirs), so the negation works — important.log gets synced, the other .log files don't.

Limitation. Detection uses static analysis on the rule's literal path prefix. Negations that begin with a glob (!**/keep/, !*/cache/) have no literal anchor to analyze and are accepted without conflict-check — if they land under an ignored ancestor at runtime, they silently fail to take effect. If you need guaranteed semantics, prefer negations with a literal prefix.

Configuration

Environment variables read at daemon startup:

Variable Default Purpose
DBXIGNORE_DEBOUNCE_RULES_MS 100 Debounce window for .dropboxignore file events.
DBXIGNORE_DEBOUNCE_DIRS_MS 0 Debounce for directory-creation events (0 = react immediately, no coalescing).
DBXIGNORE_DEBOUNCE_OTHER_MS 500 Debounce for other file events.
DBXIGNORE_LOG_LEVEL INFO Daemon log level.
DBXIGNORE_ROOT (unset) Escape hatch for non-stock Dropbox installs: overrides info.json discovery and treats the given absolute path as the sole Dropbox root. If the path doesn't exist, a WARNING is logged and no roots are returned (so dbxignore apply exits with "No Dropbox roots found").

Logs (rotated, 25 MB total):

  • Windows — %LOCALAPPDATA%\dbxignore\daemon.log.
  • Linux — two sinks, same records. The rotating file at $XDG_STATE_HOME/dbxignore/daemon.log (fallback ~/.local/state/dbxignore/daemon.log) is authoritative for offline debugging and bug-report bundling; journalctl --user -u dbxignore.service surfaces the same records via systemd-journald for live tailing and cross-service filtering.

State:

  • Windows — %LOCALAPPDATA%\dbxignore\state.json.
  • Linux — $XDG_STATE_HOME/dbxignore/state.json (fallback ~/.local/state/dbxignore/state.json).

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dbxignore-0.3.1.tar.gz (212.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dbxignore-0.3.1-py3-none-any.whl (37.9 kB view details)

Uploaded Python 3

File details

Details for the file dbxignore-0.3.1.tar.gz.

File metadata

  • Download URL: dbxignore-0.3.1.tar.gz
  • Upload date:
  • Size: 212.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dbxignore-0.3.1.tar.gz
Algorithm Hash digest
SHA256 4de05dc30d6e55c510c9194916c0b0f15605b55f8358b99a0fbeebffa52f7fd1
MD5 9824f91a081a10210c33fd79280984bd
BLAKE2b-256 701127aa6e59b48010c9cff3fe4ee1227b6ec76a3b4ceb1844f503eb2f4b5691

See more details on using hashes here.

Provenance

The following attestation bundles were made for dbxignore-0.3.1.tar.gz:

Publisher: release.yml on kiloscheffer/dbxignore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dbxignore-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: dbxignore-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 37.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dbxignore-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d554f84041b7e91eb4abb1210876e177dc4f533d91647d85e6e73164a17bfb79
MD5 d50dba4735e53976932f5c5e4e9006f2
BLAKE2b-256 98696fa693e0d6952e0ea35a363f3dfac7d9aca563577884a25b9ac548c41154

See more details on using hashes here.

Provenance

The following attestation bundles were made for dbxignore-0.3.1-py3-none-any.whl:

Publisher: release.yml on kiloscheffer/dbxignore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page