While writing a new blog/writing/notes engine for myself (I am calling it Oddity, inspired by Oddµ), I wanted the ability to show git style diffs in my text, to primarly track changes I am making. The secondary goal was also to be able to debug content manipulation that the engine itself performs.
The diffmatchpatch
library while excellent, proved to be a little unintuitive
import "github.com/sergi/go-diff/diffmatchpatch"
The library does not provide a direct diff, but rather an intermediate representation in the form of some sort of characters. It has a helper that conveniently performs per-line diff rather than full character by character diff.
dmp := diffmatchpatch.New()
t1, t2, tt := dmp.DiffLinesToChars(text1, text2)
Once intermediate representation is created, actual diff can be computed and then rehydrate the diff back to line representation
diffs := dmp.DiffMain(t1, t2, false)
diffs = dmp.DiffCharsToLines(diffs, tt)
consider these snippets of text
text1 := `# Blog post
Created: 2025-08-29
Tags: blog
Hello world`
text2 := `# Blog post
Created: 2025-08-30
Tags: blog
Hello, world!`
A simple loop print of diffs produces
# Blog post
- Created: 2025-08-29
+ Created: 2025-08-30
Tags: blog
- Hello world
+ Hello, world!
Here is the go
code for printing the diff. For convenience ignore the diffmatchpatch.DiffInsert
type
for _, d := range diffs {
suffix := " "
if d.Type == diffmatchpatch.DiffInsert {
suffix = "+ "
}
if d.Type == diffmatchpatch.DiffDelete {
suffix = "- "
}
lines := strings.Split(d.Text, "\n")
for _, line := range lines {
if line != "" {
fmt.Printf("%s%s\n", suffix, line)
}
}
}