README file from
GithubSmart Git Sync
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.
Features
- Auto-sync — commit and push after every save (debounced)
- Conflict-safe push —
git pull --rebaseruns before every push so remote changes are incorporated automatically - Pull interval — periodically pulls remote changes in the background
- Webhook trigger — exposes a local HTTP endpoint so CI/CD jobs can trigger a pull the moment someone pushes
- Action menu — click the ribbon icon to get a quick-action menu (sync, pull, pause, toggle)
- Pause — suspend sync for 30 min / 1 h / 2 h without disabling it
Requirements
- Desktop only (uses
gitCLI and the local filesystem) gitmust be in$PATH
Installation
- Copy
main.jsandmanifest.jsoninto.obsidian/plugins/lkmavi-smart-git-sync/ - Enable the plugin in Settings → Community plugins
First-time setup
If your vault is not yet a git repository:
- Open plugin settings → Repository setup → click git init
- Go to .gitignore section, configure the toggles, and click Generate .gitignore
- Create an empty repo on GitHub (no README, no license)
- Paste the clone URL into Set remote origin → click Set remote
- Run an initial push from a terminal:
git add . && git commit -m "init" && git push -u origin main - Enable Auto-sync — the plugin takes over from here
Tip: keep "Ignore .obsidian/" on if you don't want to sync Obsidian settings across devices; turn it off if you do.
Settings
| 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 |
How sync works
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.
Pull interval
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.
Webhook
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.
Exposing to GitHub Actions
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:
- Install Tailscale on your machine.
- Set a Webhook port in plugin settings.
- Click Detect — the plugin runs
tailscale ip -4and fills in the full webhook URL. - Click Copy URL and save it as
VAULT_WEBHOOK_URLin your repo secrets. - Click Copy GitHub Actions step to get a ready-to-paste workflow step.
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.
Local scripts
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.
Ribbon menu actions
Click the cloud icon in the left ribbon to open the action menu:
- Sync now — commit & push immediately
- Pull — pull latest from remote
- Enable / Disable auto-sync — toggle without going to settings
- Pause 30 min / 1 h / 2 h — suspend auto-sync temporarily
- Resume — shown instead of pause options when sync is paused
Status bar
| 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 |
License
MIT