v9.6.4✔ 435 tests passingMIT licenseAndroid · Linux · macOS

Your vault. Every device. Always in sync.

ob-sync is enterprise-grade Obsidian ↔ Git sync in a single bash script — no daemons, no plugins, no extra dependencies. Checksummed backups before every risky move, a repair mode that tells the truth about failures, and a menu wizard that connects a brand-new vault in seconds.

Why ob-sync

Serious sync, zero ceremony

Everything a phone-first vault needs to survive reality: shared-storage quirks, dead .git directories, conflicts from a second device, and 2 a.m. panic restores.

⚡

One-command sync

sync = pre-sync backup + commit + fetch + rebase + push, with a clear [ OK ] line for every step. Nothing hidden, nothing silent.

🛡️

Nine layers of defense

Repo-state guards, lock files, checksummed tar backups, fsck health checks, unborn-HEAD handling — every operation is fenced.

🩺

Honest repair new in 9.3

When repair fails, ob-sync now prints the real error instead of a bare FAIL — and on FUSE/sdcardfs filesystems it falls back to a copy-based install automatically.

🚀

Init wizard new in 9.3

Brand-new vault? Menu option 18) Init asks for your repo URL and does git init + remote wiring + first sync — no terminal gymnastics.

🌙

Cron-ready & quiet

Schedule automatic syncs from the menu, get JSON output for scripts, and let the watchdog skip credential prompts when nobody is watching.

🌍

Trilingual + 435 tests

CLI, docs and this site in English, فارسی and Español. Every release is guarded by 435 automated tests — plus a dedicated user-error suite — before it ships.

🧪

Found by the marathon 9.6.4

A real-terminal test marathon drove every menu entry, every prompt and every hostile input through a genuine pty against a credential-gated remote — and caught three field bugs: repair crashed on machines that had never run a backup (mktemp without its directory), a trailing init -y was silently ignored, and the vault switcher called an out-of-range number a "directory". All three are fixed.

Quick start

Up and running in 3 steps

Works on Android (Termux), Linux and macOS. You only need a GitHub repo (private is fine) and 2 minutes.

📱 Android — Termux

1

Install Termux from F-Droid (not Play Store), then install curl:

pkg install curl
2

Run the installer:

curl -fsSL https://raw.githubusercontent.com/CheginiSoroush/obsidian-sync-scripts/main/mobile/install.sh | bash
3

Verify, connect your vault, open the menu:

ob-sync doctor     # 1. verify the environment
ob-sync init       # 2. asks for your GitHub repo URL
ob-sync            # 3. interactive menu — or 18) Init

🖥️ Linux & macOS

1

Clone the repository:

git clone https://github.com/CheginiSoroush/obsidian-sync-scripts.git
cd obsidian-sync-scripts
2

Run the desktop installer:

./desktop/install.sh
3

Init and sync:

ob-sync init && ob-sync sync
Blind pipes: piping installers into bash is convenient but blind. Prefer to inspect first? Read mobile/install.sh or use the git clone method.

What it looks like

Real output, not a mockup

A genuine captured run of ob-sync sync integrating two remote commits.

$ ob-sync sync

  Full Synchronization
  ────────────────────────────────────────────────────────
  [1] Checking repository state
  [ OK ] Repository is in a safe state
  [2] Creating pre-sync backup
  [ OK ] Backup: pre-sync-20250612-143207.tar.gz
  [3] Committing local changes
  [ OK ] Committed 3 changed file(s)
  [4] Fetching remote state
  [5] Rebasing onto origin/main (2 remote commit(s))
  [ OK ] Integrated 2 remote commit(s)
  [6] Pushing to origin/main
  [ OK ] Pushed 1 commit(s)

  [ OK ] Sync complete — 2 commit(s) in, 1 commit(s) out

Recent releases

What's new since v9.3.0

Every one of these started as a field report from a real device.

🔄

Session vault switching 9.4.0

One machine, many vaults: menu 19) Switch moves the session to any discovered vault without rewriting the config, and init sets up git's credential helper once — so Termux stops asking for your password on every sync.

📺

Prompts you can actually see 9.4.1

Credential prompts no longer vanish into swallowed stderr (the “Termux hang”): interactive output streams through, machine modes print git said: on failure, and a stall guard cuts a dead transfer in about a minute.

🪪

The vault identity card 9.5.0

<vault>/.ob-sync/config stores the vault's REMOTE and BRANCH inside the vault and is committed with it. A clone on a new device is ready to run; a lost origin is restored from the vault's own file — never from another vault's settings.

🧗

Survives the user 9.5.1

A dedicated user-error suite (56 checks) attacks the tool with CRLF-edited configs, quoted values, typo'd remotes and deleted .git folders. The gaps it found are fixed: hand-edited values parse clean, and a missing .git now gets an honest diagnosis plus a repair hint.

🗺️

Mounted-drive vault discovery 9.5.2

Vaults on mounted drives are discovered automatically, and when nothing turns up you can type the path by hand — no more guessing where your notes live.

⬆️

Self-update on launch 9.6.0

ob-sync checks a release URL on launch and swaps itself atomically to the new version. Offline devices get an honest bilingual notice and simply keep working; OB_NO_SELFUPDATE=1 silences the check completely.

🛡️

Field-hardening backports 9.6.1

Branch injection and vault-escape closed, watchdog timeouts reported honestly, and a character-device log (/dev/full) can no longer hang a run — backported straight from the field-test campaign and covered by 95 human-error attack checks.

🎯

One-ask vault picker 9.6.2

Multi-vault devices used to be asked for a vault twice on every launch. Now the startup pick is asked once and pinned to the machine config — cron, piped runs and the next launches resolve silently, while 19) Switch stays the per-session switcher.

🔓

Prompts that answer back 9.6.3

On a phone, repair froze the moment you answered the username prompt — the watchdog had put the clone in a background process group, and git's credential read was stopped with SIGTTIN. Repair, Init and the doctor's connectivity check now run their network calls in the foreground for humans: the prompt is answerable, progress is visible, and interactive repair offers to remember your token.

Configuration

Two config layers — and your vault carries its own

ob-sync keeps device stuff on the device and vault stuff inside the vault. That split is what makes multi-device sync boring — in the best possible way.

🖥️ Device config — ~/.config/ob-sync/config

Describes this device: which vault is pinned, where backups live, branch overrides. Written by ob-sync init, editable via menu 17) EditConf — and it never leaves the machine. Environment variables (OBS_VAULT, OBS_REMOTE, …) always outrank it.

🪪 Vault identity card — <vault>/.ob-sync/config new in 9.5

Describes the vault: its REMOTE and BRANCH — two keys, nothing else. Written by init / remote, committed with the vault, and re-aligned with origin on every locked run: the card wins over a stale origin.

# .ob-sync/config — committed with the vault
REMOTE=git@github.com:you/MyVault.git
BRANCH=main
git clone git@github.com:you/MyVault.git
ob-sync init      # adopts the clone — remote already known
ob-sync sync      # green on the first run

When several sources disagree, the order is fixed: OBS_REMOTE → the vault's origin → the identity card → the device config (only for its own pinned vault). A vault with none of these refuses honestly and init asks — nothing is ever guessed. Even a deleted .git is recoverable: ob-sync repair rebuilds the metadata from the card's remote.

🔐 No tokens, ever. Neither file stores credentials — only URLs and branch names. Log in once with git's credential helper (git config --global credential.helper store or gh auth login) and every device, cron job and widget reuses it. An automated test asserts the card stays credential-free.

FAQ

Questions people actually ask

Still stuck? The troubleshooting guide and issue tracker are one click away.

Is my data safe? What if something goes wrong?
Every risky operation takes a timestamped, checksummed tar.gz backup first, and restore only rolls back from verified backups. Sync pushes are additive — ob-sync never rewrites published history with force.
Does it ever force-push or lose my commits?
No. Remote integration uses git rebase onto origin/main, so both devices' work survives. Conflicts are surfaced with clear guidance, never buried.
Repair failed on my phone with [FAIL] — what now?
Upgrade first (curl -fsSL https://raw.githubusercontent.com/CheginiSoroush/obsidian-sync-scripts/main/mobile/install.sh | bash). v9.3.0 prints the real underlying error and, on FUSE/sdcardfs filesystems where directory renames fail, falls back to a copy-based install automatically.
How do I connect a brand-new vault?
Open the menu (ob-sync) and pick 18) Init. Confirm the vault path, paste your new GitHub repo URL, and ob-sync initializes git, wires the remote and performs the first sync. Empty directory? It clones. Existing notes? It adopts them.
Does it need root or Obsidian plugins?
No root, no plugins, no daemon. Just Termux (F-Droid build) with git — the installer checks the environment for you via ob-sync doctor.
Which platforms are supported?
Android via Termux, plus native Linux and macOS. Requires Bash 4+. The same script drives all three — mobile/install.sh for Termux, desktop/install.sh elsewhere.
I cloned my vault to a new device — will it just work?
Yes — since v9.5.0 the vault carries its identity in .ob-sync/config: the remote URL and branch travel inside the repository itself. Run ob-sync init once (it adopts the clone), then ob-sync sync — no remote questions asked. And if .git is ever lost, ob-sync repair rebuilds it from the card's remote.
Where are my settings stored — is my token in there?
Two places, and neither holds secrets: the device config (~/.config/ob-sync/config — pinned vault, backups) stays on the machine, and the vault identity card (.ob-sync/config — remote URL + branch) is committed with the vault so clones self-configure. Credentials belong to git's credential helper; an automated test guarantees the card never contains tokens or passwords.

Found it useful?

A ⭐ on GitHub takes two seconds and genuinely helps other Obsidian users find ob-sync.

★ Star the repository