All notes

Check a saved patch by its changed lines, not its context

GitShellAutomation

To check that some files still hold exactly the changes in a saved patch, compare only the added and removed lines, from the patch and from git diff. Leave the context out. It belongs to whoever touched the file last, and a commit that moves it shouldn’t stop your check:

FILES="src/layouts/Base.astro src/lib/content.ts scripts/og-images.mjs scripts/content-paths.mjs src/styles/global.css"
git diff -- $FILES | grep -E '^[+-]' | grep -vE '^(\+\+\+|---) ' > /tmp/now.txt
grep -E '^[+-]' ai-tells-shared.patch | grep -vE '^(\+\+\+|---) ' > /tmp/saved.txt
cmp /tmp/now.txt /tmp/saved.txt

The first grep keeps the lines that start with + or -: the changes, plus each file’s two header lines. The second drops the headers, --- a/… and +++ b/…. cmp exits 0 when the two lists match and names the first difference when they don’t, and diff /tmp/saved.txt /tmp/now.txt shows all of it.

Why the stricter check would have failed

On 30 October, the AI tells checker for hrih.si sat uncommitted in the site’s checkout, waiting for a release job on 3 November. It shared five files with other work. So the job’s first step checked those five against ai-tells-shared.patch, to be sure they held this work’s changes and nobody else’s.

The same evening I committed a change to the note pages’ sidebar. It replaced the two CSS rules right above the checker’s two lines in global.css. The checker’s lines didn’t change, but its patch now named context that was gone:

$ git apply --check -R ai-tells-shared.patch
error: patch failed: src/styles/global.css:161
error: src/styles/global.css: patch does not apply

The job would have stopped on Tuesday morning over lines it never touched, although its 37 changed lines were the same as before. The patch was regenerated that night and the check switched to the changed lines. On 3 November it passed on the same 37 lines.

What it still catches

It still stops the release when someone else edits one of those files without committing, because their lines show up in git diff and not in the patch. It also stops when anyone changes the work’s own lines without regenerating the patch. Commits by others to the same files no longer stop it, since they become part of what git diff compares against.

It doesn’t tell you whether the patch would still apply. When you need that, regenerate the patch from the tree with git diff -- $FILES > ai-tells-shared.patch, or apply it with git apply --3way, which falls back on a three-way merge when the context has moved.

The header filter also drops a changed line whose own text starts with -- or ++ . A removed SQL comment, -- old, reads --- old in the diff. CSS and TypeScript never hit it. For SQL, match the headers by their full form instead, with grep -vE '^(\+\+\+|---) (a/|b/|/dev/null)'.