[26/33] A text save keeps what it replaced, and a history can be read - #415
Merged
Merged
Conversation
Saving from the text editor wrote straight over the file. A stop halfway through — a full disk, a killed process — left it truncated, and what the save replaced was gone in every case, even though the engine to keep it has been here since the versions landed and the office editors already feed it. The save goes through that engine now: the content is written beside the file and put in place once whole, and the state it replaces becomes a version. Somebody pressed Save, so it is marked as a state worth keeping — there is no editing session here to group it with, as there is in the office editors. A save carrying something that is not text is answered as a bad request rather than failing at the write, where it used to become a server error after the document had already been opened for writing. And a history can be read. `/api/versions` answers the versions of a file with who saved each one and where it came from, `/versions/:id/content` hands one over, `/restore` puts one back — keeping what it replaced, so going back loses nothing — `/copy` writes one beside the file under a name of its own, `/replace` writes it into another file, and a version can be labelled, pinned or deleted. A version is only ever reached through the file it belongs to, with that file's rights: asked for under another path, it does not exist. Left for the batches that bring them: reading a version as text (it wants the text service), the purge entry in the activity log, and telling an open ONLYOFFICE document that it was restored under a new key. Seven tests drive it from outside — save, save again, read what was kept, restore it, and ask for a version under the wrong file. Four of them fail when the save is put back the way it was.
This was referenced Sep 26, 2026
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Batch 26 of the plan in #373, first half: what a text save leaves behind, and reading a history. Branched from
mainand touching none of the files #410–#414 touch, so it can be merged before or after them, in any order.The versions engine landed with #406 and the office editors started feeding it in #410. Two things were still missing, and they are the same subject: the text editor wrote straight over the file, and nothing could read a history back.
What it does
PUT /api/editorwrote the file directly, so a stop halfway through left it truncated and the state it replaced was gone. It goes throughversions.saveFilenow: written beside the file, put in place once whole, and the previous content kept. Somebody pressed Save, so the state is marked as deliberate — there is no editing session here to group it with, as there is in the office editors.GET /api/versions?path=…answers a file's versions with who saved each one and where it came from;/versions/:id/contenthands one over;/restoreputs one back and keeps what it replaced, so going back loses nothing;/copywrites one beside the file under a name of its own;/replacewrites it into another file;PATCH /versions/:idlabels or pins;/versions/deleteremoves some or all.Notes for review
folderSizeHooksand the recent-destinations service that this code calls in our fork are not here, and nothing else in this tree notifies folder sizes from a write path, so both were dropped rather than invented.How it was checked
On
mainat 7b07337, Node 24 as the CI and the image use:mainuntouched, which I measured onmainitself rather than trusting a note:auth.test.js"current password is incorrect" andbrowse-hidden-files.test.jsfail every time, andusers.test.js(lockout) anduserSearchService.test.js(limit) are load-sensitive — they pass when run alone, before and after this change. Nothing new fails, and the count of tests goes up by seven;