Code Diff

approved

by Jordi

Render code diffs embedded in the middle of your notes, from pasted patches or from a Git repository. - This plugin has not been manually reviewed by Obsidian staff.

1 stars229 downloadsUpdated 8d agoMIT

Code Diff — Obsidian plugin

Show code diffs inside your notes. This plugin uses @pierre/diffs as the (beautiful) rendering engine. Please read the section about Security & Privacy before start using this extension.

⚠️ Status: early! Embedded diffs and local Git repositories work. Remote repositories and caching are not implemented yet.

Syntax

A diff lives in a fenced code block. The block is tagged code-diff.

```code-diff
diff --git a/foo.ts b/foo.ts
index 1234567..89abcde 100644
--- a/foo.ts
+++ b/foo.ts
@@ -1 +1 @@
-const foo = 1;
+const foo = 2;
```

The input format is standard git diff output.

You can add a YAML frontmatter to the block! This is how you can edit some configurations from the renderer, this example draws the diff in split view.

```code-diff
---
view: split
---

diff --git a/foo.ts b/foo.ts
index 1234567..89abcde 100644
--- a/foo.ts
+++ b/foo.ts
@@ -1 +1 @@
-const foo = 1;
+const foo = 2;
```

A diff generated from a local repository

Referencing a directory is another way to build a code-diff block. This kind of block use git, so they only run on the Desktop app. They won't work on mobile and in browsers!

This one shows the changes between two different branches:

```code-diff
repo: ../my-project
from: main
to: feature/foo
```

You can even point to a single commit or filter which files to include.

```code-diff
repo: ../my-project
commit: abc123
paths: [package.json]
```

Options

Here's a list of every setting allowed in the frontmatter.

OptionValuesDefaultMeaning
repopathThe path of a local repository. Relative paths resolve from the vault folder (configurable). The plugin expands ~.
fromrevisionHEADThe left side of the diff. Use a branch, tag, sha, or any Git revision.
torevisionHEADThe right side of the diff.
commitrevisionShows the changes that one commit introduced. Do not combine it with from or to.
pathsstring or listRestrict the diff to these paths.
contextintegerGit defaultThe lines of context that you ask Git for.
viewunified, splitunifiedLayout of the diff. inline and side-by-side are accepted aliases.
themeauto, light, darkautoWith auto, the theme follows Obsidian and changes with it.
lineNumbersbooleantrueShow line numbers.
wrapbooleanfalseWrap long lines instead of scrolling.
fileHeaderbooleantrueShow the header of each file.
highlightword, char, nonewordHighlight the changed part inside a line.
lightTheme / darkThemebundled theme namepierre-light / pierre-darkOverride the syntax theme.
fontFamilyCSS font-familyObsidian's monospace fontThe font for the diff content.
maxHeightCSS length or none60vhThe maximum height of the scroll region for the diff. Use none to let it grow with the note.

You can set defaults for the presentation options in the plugin settings. A block always wins over the setting.

Generated diffs are limited to repositories inside the current vault by default. To use a local repository elsewhere, explicitly enable Allow read-only Git outside vault in the plugin settings.

Security & privacy

This plugin is flagged as shell execution because generating a diff from a repository means running git.

  • What runs. Only the git executable already installed on your machine, and only these read-only subcommands:
    • git rev-parse to resolve revisions.
    • git diff / git show to produce the patch. The plugin never writes to a repository, never stages, commits, pushes or fetches.
  • How it runs. Git is spawned directly with an argument list:
    • execFile, so nothing in a note can be interpreted as shell syntax.
    • External diff drivers, text-conversion filters and pagers configured in a repository are explicitly disabled using --no-ext-diff, --no-textconv and --no-pager.
    • Git will never prompt for credentials.
    • Every invocation has a 30-second timeout and a bounded output size.
  • When it runs. Only when a code-diff block sets repo:. Blocks with a pasted diff don't need to touch git, the job is already done!
  • What it can read. By default, a repo: block can only point at a local repository inside the current vault. Reading a repository outside the vault requires the user to explicitly enable Allow read-only Git outside vault in the plugin settings. Please treat repo: blocks in notes you did not write yourself with the same care as any other content that references files on your machine.
  • Network & telemetry. Nada. The plugin makes no network requests and collects no data. Remote repository URLs are currently recognised but rejected.

Install for development

npm install
npm run build
node scripts/install.mjs "/path/to/Vault"

Then reload Obsidian. Enable Code Diff under Settings → Community plugins.

During development, run npm run dev. It rebuilds the plugin on change. Then run the install script again, or just symlink the folder

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.