Skip to content

About

Simple CLI for Google Drive sync that allows you to have .driveignores.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

driveignore

ci

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.

requirements

  • Google Drive for desktop on Windows or macOS
  • the source folder and the Drive folder on the same filesystem — hardlinks cannot cross volumes

installing

Homebrew (macOS)

brew tap ranokay/driveignore https://github.com/ranokay/driveignore
brew trust ranokay/driveignore
brew install --cask driveignore

brew trust is required by recent Homebrew versions for casks from third-party taps.

Scoop (Windows)

scoop bucket add driveignore https://github.com/ranokay/driveignore
scoop install driveignore

install script (macOS, Linux)

curl -fsSL https://raw.githubusercontent.com/ranokay/driveignore/main/install.sh | sh

Installs 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" sh

Go

go install github.com/ranokay/driveignore@latest

Requires Go 1.27 or newer; make sure $(go env GOPATH)/bin is on your PATH.

manual archives

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.

how to use

  1. Create an empty folder and add it to Google Drive for desktop's mirror list.
  2. Create a .driveignore in the root of the folder you want to sync.
  3. 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 for upload, diff, unify, watch
  • -M, --merge-ignores: merge the global and the local .driveignore
  • --force (upload only): overwrite existing files with the same name
  • --dry-run (clean, watch, guard): clean lists the files that would be removed without removing them; watch and guard print 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. clean and diff treat 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 (diff only): 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.

watch

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.

running the watcher at login (macOS)

--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" --install

The 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.

guard (macOS)

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" --install

The 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.

global .driveignore

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.

ignore patterns

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.

hardlinks and copies

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.

platform support

  • Windows amd64, Windows arm64
  • macOS amd64, macOS arm64
  • Linux amd64, Linux arm64 (no official Google Drive client; useful with mounted drives, best-effort)

development

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 clone

The 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.

license

Apache-2.0. Originally written by Marcin Wojnarowski, later maintained by shilangyu; this fork continues the project.

About

Simple CLI for Google Drive sync that allows you to have .driveignores.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages