Silence Git Sync

approved

by czhhbp

静默后台同步 Obsidian 笔记库到 Git 远程仓库:定时提交推送、自动合并、冲突零丢失。Silently commit, merge and push your vault to a Git remote in the background. - This plugin has not been manually reviewed by Obsidian staff.

14 downloadsUpdated 6d agoMIT

Silence Git Sync

Version License

Sync your vault to a Git remote silently in the background. Edit your notes and forget about it — the plugin commits, merges, and pushes on its own. No popups, no interruptions; you only hear from it when something goes wrong.

⚠️ Desktop only (Windows / macOS / Linux). The mobile version of Obsidian runs in a sandboxed container where the system Git executable is unavailable, so this plugin disables syncing when loaded on mobile. See Android for why, and for the Termux-based workaround.

Features

FeatureDescription
🔗 One-field remote setupJust paste an HTTPS URL. A missing origin is created automatically, and URL changes are applied for you.
🤫 Silent background syncSyncs automatically N minutes after you stop editing, plus a fixed-interval sync. Never shows a popup.
🧠 Zero-loss conflictsOn conflict, your local text is kept as-is and the remote version is saved as xxx.sync-remote.md. Both sides get committed.
🚫 Managed ignore pathsOne path per line in settings, written into a marked block in .gitignore, and applied to already-tracked files immediately.
🔐 Safe token injectionA Personal Access Token is injected into HTTP headers via a temporary GIT_CONFIG_GLOBAL file — never written to .git/config.
📊 Status bar feedbackThe status bar shows Last sync: HH:MM:SS success/failure.
⌨️ Manual triggerLeft-ribbon icon, or the Ctrl/Cmd + Shift + S hotkey.

Installation

Manual installation

  1. Download main.js, manifest.json, and styles.css from Releases.
  2. Place them into <your-vault>/.obsidian/plugins/silence-git-sync/.
  3. Enable Silence Git Sync under Settings → Community plugins.

Requirements

  • Git must be installed and the git command available on your PATH (on Windows, tick Add Git to PATH during installation).
  • Your vault must either already be a Git repository, or you must provide a remote URL in the plugin settings.

To verify: run git --version in your vault root — it should print a version number.

Android

This plugin does not run on Android, even if you have installed Git through Termux and it works perfectly inside a Termux shell. The reason is sandbox isolation, not a configuration switch:

  • Obsidian for Android runs inside a Capacitor/WebView container with no Node.js runtime. require("child_process") — the only way this plugin can spawn git — does not exist there.
  • The Git you installed in Termux lives in Termux's private Linux user space (e.g. /data/data/com.termux/files/usr/bin/git). Only processes started inside Termux can execute it.
  • Obsidian and Termux have separate UIDs, separate file-system views, and separate process trees. There is no supported bridge between them, so the plugin cannot call Termux's Git.

Because of this, the plugin detects the platform at load time and disables syncing on mobile instead of failing to load. Ripping out that check would not make sync work — it would only make the plugin throw and break.

Workaround: sync from Termux, not from Obsidian

If you want Git-based backup of your vault on Android, run Git from Termux on a schedule and treat the vault as an ordinary folder. Obsidian never needs to know about Git.

  1. Install Termux and Git, and grant Termux access to shared storage:
    pkg update && pkg install git openssh cronie
    termux-setup-storage   # approve the permission prompt
    
  2. Point the vault path at your shared-storage copy. On modern Android the vault usually lives under:
    cd ~/storage/shared/<YourVaultFolder>
    

    If Android's scoped storage blocks the path, keep a copy of the vault inside Termux's own home (~/vault) and sync that instead — or use Termux's termux-setup-storage shortcut folders.

  3. Initialise it as a repository and add your remote (use a token in the URL or an SSH key):
    git init
    git remote add origin https://<TOKEN>@github.com/<user>/<repo>.git
    git add -A && git commit -m "init"
    git push -u origin main
    
  4. Schedule a periodic commit-and-push with cronie:
    crontab -e
    
    Add a line such as (every 30 minutes):
    */30 * * * * cd ~/storage/shared/<YourVaultFolder> && git add -A && git commit -m "auto: $(date +\%F_\%T)" && git push origin main >> ~/sync.log 2>&1
    
    Start the daemon with crond, and keep Termux alive (disable battery optimisation for Termux, or use termux-job-scheduler).

Keeping the vault inside a Git repository that Android also syncs elsewhere means .obsidian/ workspace files churn frequently — add a sensible .gitignore in the vault root to keep the history clean.

Settings

SettingDefaultDescription
Remote HTTPS URL (optional)emptye.g. https://github.com/user/repo.git. Leave empty to reuse the vault's existing Git repository and origin.
Access token (optional)emptyA GitHub/GitLab Personal Access Token (needs repo / write_repository scope). Leave empty to fall back to the system credential manager.
.gitignoreemptyOne path per line. When empty, all dot-prefixed files and folders are ignored by default.
Sync delay after edit (minutes)5How long to wait after you stop editing before syncing.
Scheduled sync interval (minutes)30How often to run an additional sync.

How it works

flowchart TD
    A[Trigger: after edit / scheduled / manual] --> B[Verify repository and origin]
    B --> C[Write .gitignore marker block]
    C --> D[Apply ignore rules: ls-files -ci + rm --cached]
    D --> E{Local changes?}
    E -- Yes --> F[git add -A and commit]
    E -- No --> G[Skip commit]
    F --> H[git fetch origin]
    G --> H
    H --> I{Remote updates?}
    I -- Yes --> J[git merge origin/branch]
    I -- No --> M[git push]
    J --> K{Merge conflict?}
    K -- Yes --> L[Keep local text + save remote as .sync-remote copy + commit]
    K -- No --> M
    L --> M
    M --> N[Update status bar]

On the conflict strategy: this plugin deliberately does not use silent overrides such as -X ours. When the same file has changed on both sides, it lets Git raise a real conflict, then:

  1. Keeps the local version under the original filename (git checkout --ours).
  2. Saves the remote version as filename.sync-remote.ext.
  3. Commits both together.

This way neither side's content is ever lost, and you can compare and merge them by hand afterwards. Repeated syncs will not overwrite an existing copy.

Differences from obsidian-git

Silence Git Syncobsidian-git
Sync strategymergemerge / rebase / reset
Conflict handlingKeeps both sides; remote saved as a copyMarks conflicts for the user to resolve
InterfaceMinimal settings, no extra viewsFull source control view, history view, diff view
GoalFrictionless background backupA complete Git client experience
MobileNot supported — sandbox has no Git access (see Android)Experimental (isomorphic-git, unstable)

Do not enable both at once — they would operate on the same repository concurrently and can cause conflicts or index corruption.

Development

git clone https://github.com/czhhbp/obsidian-silence-git-sync.git
cd obsidian-silence-git-sync
npm install

# Development mode (watch and rebuild)
npm run dev

# Production build (type check + minified main.js)
npm run build

Releasing

The repository is wired up with GitHub Actions: pushing a tag builds and publishes a Release automatically, so no manual packaging is needed.

npm version patch        # 1. Bump the version (syncs manifest.json / versions.json)
git push origin main     # 2. Push the commit
git push origin --tags   # 3. Push the tag -> triggers build and release

After a tag is pushed, the workflow runs: install dependencies → type check and bundle → verify build artifacts → compare the tag with the version in manifest.json → create the Release and upload main.js, manifest.json, styles.css, plus a bundled silence-git-sync.zip.

If the tag name (with an optional v prefix stripped) does not match the version in manifest.json, the workflow fails on purpose to prevent publishing artifacts for the wrong version.

WorkflowTriggerPurpose
.github/workflows/ci.ymlpush / PR to mainVerify the build on Node 18 and 20, upload artifacts
.github/workflows/release.ymlany tag pushBuild, verify, then create the Release automatically

Project structure

silence-git-sync/
├── main.ts              # Entry point: lifecycle, timers, status bar, sync orchestration
├── src/
│   ├── constants.ts     # Message and marker constants
│   ├── git.ts           # git subprocess wrapper, platform detection, token injection
│   ├── sync-engine.ts   # Sync engine: repo checks, ignore rules, conflict preservation
│   ├── settings.ts      # Settings shape and defaults
│   └── settings-tab.ts  # Settings UI
├── esbuild.config.mjs   # Build script
├── manifest.json        # Plugin manifest
├── styles.css           # Status bar and settings panel styles
└── versions.json        # Version to minimum app version mapping

The top-level .github/workflows/ directory holds the automated build and release definitions.

License

MIT

For plugin developers

Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.