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.2.tar.gz (217.6 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.2-py3-none-any.whl (38.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: dbxignore-0.3.2.tar.gz
  • Upload date:
  • Size: 217.6 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.2.tar.gz
Algorithm Hash digest
SHA256 abcad02f1a5645523416ad711f1e031522150abf21adcceaf32675a88cae10b6
MD5 2099398220b474d0cc6177e97d54d675
BLAKE2b-256 4276f2aae039c93092396afe140f1cfc944984538aad9ba5c50315bb2efb41cf

See more details on using hashes here.

Provenance

The following attestation bundles were made for dbxignore-0.3.2.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.2-py3-none-any.whl.

File metadata

  • Download URL: dbxignore-0.3.2-py3-none-any.whl
  • Upload date:
  • Size: 38.2 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 7ac5ea38bcb94c9c3ee4233febaf97a0bc8b0332e2c4644c097e9acf0f935061
MD5 09d6d56c1f2e3fb253ae9b82448bd818
BLAKE2b-256 b4ff1ea0d01464af26045768e893ec62efc153dbe28f4afd68270e2d0229a1f1

See more details on using hashes here.

Provenance

The following attestation bundles were made for dbxignore-0.3.2-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