# Obsidian config — global + per-vault fork model Two-tier Obsidian configuration: - **Global config** — `ssh://git@gitea.bchen.dev:2222/brendan/obsidian-global-config.git` — shared settings (plugins, hotkeys, appearance, theme) used by **every** vault. - **Per-vault config** (this repo, e.g. `obsidian-config`) — a *fork* of the global repo: the global config **plus** files specific to one vault that must sync with that vault but never be published globally. Each vault's `.obsidian` is a git submodule pointing at that vault's per-vault repo, which has the global repo configured as its `upstream` remote. ``` vault/.obsidian ──submodule──► obsidian-config (per-vault, downstream) │ remote: upstream ▼ obsidian-global-config (shared, upstream) ``` ## Tiers | Tier | Examples | Lives in | |---|---|---| | **Global** (shared everywhere) | `app.json`, `appearance.json`, `hotkeys.json`, `templates.json`, `daily-notes.json`, `core-plugins.json`, `community-plugins.json`, `types.json`, `themes/**`, plugin code, most plugin `data.json` | global upstream → flows to every vault | | **Vault-specific** (synced, never published) | `bookmarks.json` | per-vault repo only — never pushed upstream | | **Machine-local** (not synced) | `workspace.json`, `workspaces.json`, `workspace-mobile.json`, `.DS_Store` | gitignored everywhere | ## Daily workflow Run from a vault root (where `.obsidian` is the submodule). **Change a vault-specific setting** (a bookmark, the daily-notes folder) — stays in this vault: ```bash git -C .obsidian add -A git -C .obsidian commit -m "..." git -C .obsidian push git add .obsidian && git commit -m "bump config" && git push # record the pointer ``` **Pull global changes down** — conflict-free; never touches your vault-specific files: ```bash git -C .obsidian fetch upstream git -C .obsidian merge upstream/main git -C .obsidian push # save merged result to this vault's repo git add .obsidian && git commit -m "pull global config" && git push ``` **Change a global setting** — make it in a clone of the **global** repo, push there, then run the pull-down above in each vault: ```bash git -C /path/to/obsidian-global-config add -A git -C /path/to/obsidian-global-config commit -m "..." git -C /path/to/obsidian-global-config push ``` > Promoting a *global* change you happened to make **inside a vault** isn't a plain push > (your per-vault history has vault-specific commits in the way) — cherry-pick it onto an > `upstream`-tracking branch and push that. Editing global settings in the global clone > avoids this entirely. ## Which files are vault-specific The current list is just `bookmarks.json`. To make a plugin's settings vault-specific, add `plugins//data.json` to the denylist and remove it from the global repo. The denylist is enforced by a `pre-receive` hook on the global repo, which rejects any push that touches a vault-specific path (so a stray cherry-pick can't publish private data). See the project notes for the hook script. ## Bootstrapping a new vault - **Only needs the global config** → point the submodule straight at the global repo: ```bash git submodule add ssh://git@gitea.bchen.dev:2222/brendan/obsidian-global-config.git .obsidian ``` - **Needs its own private tracked config** → create an empty gitea repo for it, seed it from the global repo, add it as the submodule, and set `upstream` to the global repo. (Ask to have this scripted.) > Do this **before opening the vault in Obsidian** — Obsidian auto-creates a default > `.obsidian/` on first open, which blocks the submodule add. Delete it first if present. > On first open the vault starts in **Restricted Mode** — click **Trust author and enable > plugins** to load the configured community plugins.