Obsidian plugin that keeps your vault in sync with a Git remote. Every save triggers a debounced commit + push. Remote changes are pulled automatically on a configurable interval and can also be triggered on-demand via a local webhook.
git pull --rebase runs before every push so remote changes are incorporated automaticallygit CLI and the local filesystem)git must be in $PATHmain.js and manifest.json into .obsidian/plugins/lkmavi-smart-git-sync/If your vault is not yet a git repository:
git add . && git commit -m "init" && git push -u origin main
Tip: keep "Ignore .obsidian/" on if you don't want to sync Obsidian settings across devices; turn it off if you do.
| Setting | Default | Description |
|---|---|---|
| Auto-sync | off | Commit & push on every save |
| Pull on startup | off | Fetch + pull when Obsidian opens |
| Push debounce | 0 min 30 sec | Wait after last change before committing. 0 m 0 s = disabled. |
| Pull interval | 0 min 30 sec | Background fetch+pull cadence. 0 m 0 s = disabled. |
| Commit message | auto: sync {date} |
{date} is replaced with current timestamp |
| Branch | main |
Remote branch to push/pull |
| Webhook port | 0 (off) | Local port for the HTTP trigger endpoint |
| Webhook secret | — | Optional Authorization: Bearer <secret> guard |
| Ignore .obsidian/ | on | Include .obsidian/ in generated .gitignore |
| Ignore OS files | on | .DS_Store, Thumbs.db, desktop.ini… |
| Ignore IDE files | on | .idea/, .vscode/, *.iml, .fleet/… |
| Custom entries | — | Extra lines appended to the generated .gitignore |
file saved
└─ debounce (default 30 s)
└─ git add .
└─ git diff --cached (skip if nothing staged)
└─ git commit -m "auto: sync <timestamp>"
└─ git pull --rebase origin <branch> ← absorbs remote changes
└─ git push origin <branch>
If pull --rebase hits a real conflict (same lines edited by two people), the sync fails and a Notice is shown. Resolve the conflict manually in a terminal, then use Sync now from the ribbon menu.
On every tick the plugin runs git fetch origin <branch> to update the remote ref, then compares HEAD vs origin/<branch>. A pull only happens when the commits differ — if already up to date, nothing happens and no notice is shown. The fetch + pull is skipped if a sync is already in progress or sync is paused.
The plugin can start a local HTTP server:
POST http://127.0.0.1:<port>/sync
Authorization: Bearer <secret> ← only if secret is set
A 202 ok response is returned immediately; the pull runs in the background.
The webhook binds to 127.0.0.1, so it is not reachable from the internet by default. Use a tunnel to expose it:
Option A — Tailscale (recommended for personal vaults)
The plugin can detect your Tailscale IP automatically:
tailscale ip -4 and fills in the full webhook URL.VAULT_WEBHOOK_URL in your repo secrets.Full workflow example:
# .github/workflows/notify-vault.yml
on:
push:
branches: [main]
jobs:
notify:
runs-on: ubuntu-latest
steps:
- uses: tailscale/github-action@v2
with:
authkey: ${{ secrets.TAILSCALE_AUTHKEY }}
- name: Notify Smart Git Sync
run: |
curl -fsS -X POST \
-H "Authorization: Bearer ${{ secrets.VAULT_WEBHOOK_SECRET }}" \
${{ secrets.VAULT_WEBHOOK_URL }}
Option B — cloudflared tunnel
cloudflared tunnel --url http://127.0.0.1:<port>
Copy the generated *.trycloudflare.com URL, add it as VAULT_WEBHOOK_URL in your repo secrets, then:
- name: Notify Smart Git Sync
run: |
curl -fsS -X POST \
-H "Authorization: Bearer ${{ secrets.VAULT_WEBHOOK_SECRET }}" \
${{ secrets.VAULT_WEBHOOK_URL }}/sync
Option C — ngrok
ngrok http 127.0.0.1:<port>
Same as cloudflared: copy the forwarding URL and use it in your workflow.
If you just want to trigger a pull from a script on the same machine:
curl -X POST http://127.0.0.1:<port>/sync
No tunnel needed.
Click the cloud icon in the left ribbon to open the action menu:
| Text | Meaning |
|---|---|
sync: on |
Auto-sync enabled, idle |
sync: pending… |
Waiting for debounce timer |
sync: pushing… |
Commit + push in progress |
sync: ok 14:32 |
Last push succeeded at 14:32 |
sync: failed ✗ |
Last operation failed (see Notice for details) |
sync: paused until 15:00 |
Paused until 15:00 |
sync: off |
Auto-sync disabled |
MIT