Building Diffs With Go

Created 2025-08-30

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)
		}
	}
}