martinlegend_neogdsync/README.md
ml2310 b0de078e15
v1.0.9: fix data-loss and correctness bugs across the sync engine (rebased onto v1.0.8) (#5)
Correctness:
- Edits made while a sync runs are no longer dropped. Vault event handlers
  now ignore only paths the sync itself wrote (Syncer.syncWrites) instead of
  suppressing all events behind a global flag, and pending ops are cleared
  per-op right after success instead of in a bulk sweep that also wiped
  ops re-queued mid-sync.
- Renames now propagate to Drive: handlePush compares the Drive-side name
  and calls files.rename, so a local a.md -> b.md no longer leaves the old
  name on Drive (which later caused duplicate uploads after a rebuild).
- A 'modify' op with no index entry (index lost/reset) looks the file up on
  Drive by path before uploading, preventing duplicate files on Drive.
- Excluded paths queued in pendingOps are cleared instead of sticking in
  the "N pending" counter forever; exclusion logic is now shared between
  event handlers and the sync engine (src/exclude.ts), so user glob
  patterns apply consistently. computeDiff no longer reports
  newly-excluded snapshot entries as deletions.
- Files first seen via unknown Drive changes (syncedAt=0) now go through
  conflict handling instead of silently overwriting the remote copy.
- index.db is written via tmp-file + rename with recovery on load, so a
  crash mid-save can no longer silently reset the index.
- Multipart upload boundary is randomized; a file containing the fixed
  boundary string no longer corrupts the upload.

Auth / settings:
- authProxyUrl is actually used now (it was silently ignored) and is
  editable in settings; DriveApi credentials update in place so PathIndex
  never holds a stale instance; token cache is keyed by token+proxy.
- Exclude patterns are editable in settings (README advertised this but
  there was no UI).

Performance / UX:
- Force Pull and pull-new-from-Drive download with a small concurrency
  pool (settings.concurrency, previously dead config).
- Unknown-change resolution fetches each file's metadata once instead of
  twice.
- First run with a non-empty vault shows a notice explaining that an
  initial Force Push/Pull is required.

Security / hygiene:
- OAuth proxy escapes HTML in the callback pages (reflected XSS via
  ?error=...), and README now accurately describes that token refresh goes
  through the proxy and how to self-host it.
- Removed stale compiled artifacts (src/*.js) and dead code
  (listRevisions); fixed package.json metadata (MIT, author, scripts).
- Added vitest with unit tests for exclusion, snapshot diffing, and index
  persistence/recovery (17 tests).


Claude-Session: https://claude.ai/code/session_011DimwV9zDr1ViCXRCZPxC9

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-13 11:56:55 +08:00

2.4 KiB

NeoGDSync logo

NeoGDSync

Lightweight Google Drive sync plugin for Obsidian.

Features

  • Smart Sync — auto conflict detection, only syncs changed files
  • Force Push — local vault → Google Drive
  • Force Pull — Google Drive → local vault
  • Conflict handling — saves Drive copy as a conflict file, never overwrites silently
  • Path-based index — fast, no full crawl needed after first sync
  • Version history — optionally keep file revisions on Drive
  • Configurable excludes — glob patterns to skip files/folders
  • URI handlerobsidian://neogdsync?mode=smart|push|pull for automation

Setup

  1. Install the plugin
  2. Go to Settings → NeoGDSync
  3. Enter your Google OAuth2 Refresh Token
  4. Enter your Google Drive Vault Root Folder ID (the Drive folder that maps to your vault root)
  5. Click the ☁ ribbon icon or run a command to sync

Getting a Refresh Token

This plugin uses a standard OAuth2 refresh token with read/write access to Google Drive.

You can obtain one via:

The refresh token is stored locally in your vault's plugin data. To obtain short-lived access tokens, the plugin sends the refresh token to an OAuth proxy (by default the NeoGDSync Cloudflare Worker, see oauth-proxy/worker.js), which exchanges it with Google and returns the access token. The proxy does not store tokens. If you prefer not to route through the shared proxy, deploy your own Worker (instructions in oauth-proxy/worker.js) and set its URL in Settings → NeoGDSync → Auth proxy URL.

Commands

Command Description
Smart Sync Detect and sync only changed files, with conflict detection
Force Push Upload all local changes to Drive
Force Pull Download all Drive changes to local
Rebuild Drive Index Re-crawl Drive vault folder to rebuild index
Show Conflicts View detected conflicts

URI Handler

Trigger sync from outside Obsidian (Shortcuts, scripts, etc.):

obsidian://neogdsync?mode=smart
obsidian://neogdsync?mode=push
obsidian://neogdsync?mode=pull

License

MIT