Aug 21, 2026

Ten versions back

Part 7 of 7 of ./blog.sh v1.3

The engine has never had an undo. Editing a post rewrote its file, and what the post said an hour ago was gone — not because anything went wrong, but because a save is a save.

Now the previous text is kept before every overwrite, and [v] in a post's properties puts one back.

Before every overwrite, not just before an edit

A re-import is an overwrite too, and that turns out to be the case where this earns its keep. Editing a post by hand is deliberate; re-importing a source over a post you have since tidied up is the accident that eats an evening's work, and up to now the only recovery was a backup.

Ten per post, newest first.

Picked by recognising it, not by reading a timestamp

The list is one you walk like every other list in the wizard, and the row under the cursor shows what that version said — its title, or its opening words if it hasn't got one. Ten timestamps tell you nothing about which one is the version you want. Ten opening sentences tell you immediately.

Confirming is one keypress, and it can be that cheap because restoring loses nothing: the current text is kept as a version of its own before it is replaced. A wrong choice is one [v] away from being walked back.

What it doesn't cover

Text only. Images are not versioned, and the line above the list says so rather than leaving you to find out. A restore brings back words, and the pictures are whatever the post's media directory holds now.

Ten. The eleventh save pushes the oldest one out. That is a decision about disk rather than about safety — but it did produce a bug worth naming: ten re-imports that changed nothing used to fill all ten slots, quietly pushing out the hand-edited state the versions exist to protect. A version identical to the newest one stored is no longer written.

A save always wins. If the versions directory cannot be written — a full disk, the wrong permissions — the copy is skipped and the save goes through anyway, silently. That is deliberate and I would choose it again: the point of this is to lose less, and refusing somebody's save because the undo could not be filed would lose more. It does mean the undo is a courtesy rather than a guarantee, which is the difference between it and a backup.

They live with the content. content.nosync/versions/, beside the posts. They travel with a post into the trash and back out again, and a restore from a backup that copied only posts/ brings back the archive and loses the undo. The backup list in the docs says which paths matter; this is a new line on it.

The key appears when there is something to restore

A post that has never been edited shows no [v], because an undo with nothing behind it is a key that teaches you not to trust the keys.

Comments