driveignore keeps parts of a folder out of Google Drive for desktop. It reads
.driveignore files (same pattern syntax as .gitignore) and hardlinks the
files that should sync into your Drive folder. No file copies, no repeated CLI
runs: Google Drive sees changes through the links.
This is a maintained fork of shilangyu/driveignore.
- Google Drive for desktop on Windows or macOS
- the source folder and the Drive folder on the same filesystem — hardlinks cannot cross volumes
brew tap ranokay/driveignore https://github.com/ranokay/driveignore
brew trust ranokay/driveignore
brew install --cask driveignorebrew trust is required by recent Homebrew versions for casks from third-party
taps.
scoop bucket add driveignore https://github.com/ranokay/driveignore
scoop install driveignorecurl -fsSL https://raw.githubusercontent.com/ranokay/driveignore/main/install.sh | shInstalls the latest release to ~/.local/bin and verifies the download
against the release checksums. Override the destination with INSTALL_DIR
and pin a version with VERSION:
curl -fsSL https://raw.githubusercontent.com/ranokay/driveignore/main/install.sh | \
VERSION=v1.2.0 INSTALL_DIR="$HOME/bin" shgo install github.com/ranokay/driveignore@latestRequires Go 1.27 or newer; make sure $(go env GOPATH)/bin is on your PATH.
Download the archive for your OS from the
releases, extract it, and
move the driveignore binary (driveignore.exe on Windows) into a directory
on your PATH — for example ~/.local/bin on macOS/Linux, or
%USERPROFILE%\bin added to PATH on Windows. Running the binary from the
extraction directory only works while you stay there, so prefer one of the
options above. Winget is not published yet; Windows users can use Scoop or the
zip archive.
- Create an empty folder and add it to Google Drive for desktop's mirror list.
- Create a
.driveignorein the root of the folder you want to sync. - Run
driveignore unify [path to your Drive folder]from the source folder.
The current directory is mirrored into the Drive folder with the .driveignore
applied. Because the mirrored files are hardlinks, editing either copy updates
both and Google Drive handles the rest.
Usage:
driveignore [command]
Commands:
clean cleans the drive folder from files that no longer exist in the source
diff compares the source with the drive folder
global prints the path to the global .driveignore
guard keeps ignored paths in a My Drive folder sealed from sync (macOS)
unify uploads the source and removes legacy files in one go
upload hardlinks the source into the drive folder
watch keeps the source and the drive folder reconciled continuously
Flags:
--verbose print what is happening
-h, --help help for driveignore
Every command documents its flags in --help. The shared flags are:
-i, --input(default.): source directory forupload,diff,unify,watch-M, --merge-ignores: merge the global and the local.driveignore--force(uploadonly): overwrite existing files with the same name--dry-run(clean,watch,guard):cleanlists the files that would be removed without removing them;watchandguardprint every action a pass would take without changing anything--once,--interval(watch,guard): run a single pass, or set the base poll interval;--one-way(watch) makes the source authoritative--trash-dir(watch): directory local deletions move to (default~/.Trash; set it where that directory does not exist, for example on Linux or Windows)--install,--uninstall(watch,guard, macOS only): install or remove the launchd agent that keeps the pair reconciled, or the folder sealed, from login--prune-ignored(clean,unify): also remove drive files excluded by.driveignore, even when the source still contains them--copy(upload,unify): copy files instead of hardlinking them, for filesystems without hardlink support.cleananddifftreat files with equal size and modification time as in sync (recent timestamps are verified by content), so copies are kept and refreshed like links are.--exit-code(diffonly): exit with status 1 when differences exist--version: print the version and exit
When stderr is an interactive terminal, upload, unify, clean and diff
report progress while they walk: a status line about once a second and a
closing summary. With --verbose the walk prints one line per action
instead; piped output stays unchanged.
driveignore watch "/path/to/your drive folder" -i "/path/to/source"watch keeps the pair reconciled continuously instead of requiring a manual
unify after every structural change. Content edits stay instant because both
copies are hardlinks to the same file, so a pass only has to look at structure:
created, deleted, renamed and replaced paths. A per-pair journal records which
paths were proven synced, so the watcher can tell a new local file from one
deleted on the drive side. Local deletions the watcher performs move to the
Trash, so every removal is recoverable. The two trees must be on one
filesystem: watch proves hardlink support before its first pass and refuses to
run when it cannot.
Run --once for a single pass, --dry-run to print exactly what a pass would
do without changing anything, and --one-way to make the source authoritative.
Passes run --interval apart (2 seconds by default) while changes keep
flowing, and back off towards 60 seconds while idle or after a failure; a pass
that acted returns to the base.
--install writes a launchd agent for the pair and loads it, so the watcher
starts at login and is restarted whenever it exits:
driveignore watch "/path/to/your drive folder" -i "/path/to/source" --installThe agent runs the same binary that invoked the command and logs stdout and
stderr to ~/Library/Logs/driveignore/watch-<pair>.log, one file per pair.
--uninstall unloads the agent and removes it; the logs stay. Both flags are
macOS-only.
driveignore guard "/path/to/folder in My Drive"guard is for working directly inside My Drive instead of mirroring a folder
into it. It reads the .driveignore in the guarded folder (falling back to the
global one), watches for changes, and stamps every matching path with the File
Provider attribute Google Drive for desktop honors as "keep this on disk, leave
it out of the cloud". A sealed directory covers everything created inside it
later, so an install or a build cannot leak; removing a rule unstamps the path
again. Junk that was already uploaded loses its cloud copy on the first pass.
The attribute is an Apple File Provider mechanism that Google's client honors today. It is not a documented Google feature, so a Drive update could stop respecting it; the failure is visible, junk starts uploading, and the next pass reverses it. The window between a path appearing and being stamped is about one poll interval.
Run --once for a single pass, --dry-run to see what would be stamped, and
--install to keep it running from login:
driveignore guard "/path/to/folder in My Drive" --installThe agent logs to ~/Library/Logs/driveignore/guard-<folder>.log. Nested
.driveignore files inside the guarded folder are not read yet; the folder's
own file is the contract. Symlinks and Google's .gdoc stubs are never
stamped. Do not point guard and watch at the same folder.
driveignore global prints the path to a global .driveignore (creating it if
needed). Uploads from a directory without its own .driveignore use the global
one; pass --merge-ignores to combine both.
Patterns follow the same rules as .gitignore: *, ?, **, ! negation,
leading / anchoring and trailing / for directory-only matches.
.driveignore files can live in subdirectories. Each one applies to its own
subtree, its patterns are anchored to the directory containing the file, and
deeper files override shallower ones — the same way .gitignore works.
Symlinks are skipped: they are neither uploaded nor followed, and clean
leaves symlinks inside the drive folder untouched.
By default upload and unify hardlink files. Nothing is duplicated and
edits on either side stay in sync through Google Drive, but the source and the
drive folder must be on the same filesystem.
If hardlinks are not supported (virtual drives, FAT/exFAT, network shares),
pass --copy: files are copied, preserving permissions and modification
times, and later runs replace stale copies only. Copy mode is a one-way
mirror — changes made in the drive folder are overwritten by the next
unify.
- Windows amd64, Windows arm64
- macOS amd64, macOS arm64
- Linux amd64, Linux arm64 (no official Google Drive client; useful with mounted drives, best-effort)
mise install # install the pinned Go toolchain and tools
mise run check # formatting, vet, lint and tests
mise run test:race # tests with the race detector
mise run bench # benchmarks
mise run hooks:install # install the hk pre-commit hook for this cloneThe hooks run gofmt, golangci-lint, go mod tidy, actionlint and pinact on
staged files; bypass a run with HK=0 git commit ... or git commit --no-verify.
hk check --all runs the same steps over the whole repository.
Apache-2.0. Originally written by Marcin Wojnarowski, later maintained by shilangyu; this fork continues the project.