#153 · Let a timeline stop keeping saved history
- timeline-app
- pull request
Closes #136. An owner can now turn off **Keep saved history** in a timeline's **Sharing & settings**. It's on by default. It's meant for logs and other high-volume timelines whose past revisions nobody reviews. ## Behaviour - **Turning it off:** - deletes the content of the timeline's past revisions at once and refunds what they were charged; - keeps revisions others still read: those copies' history reads through to, those forks were made from, other timelines' heads, and those pull requests refer to (with the patches they're stored against); - keeps every revision's place (author, time, parents), so ancestry stays intact; - shows a confirmation dialog first, stating how much storage it frees. - **While it is off:** - saves record revisions without content, charged nothing for history; - the head is read from the live index, so it can still be opened, exported and copied; - the history page lists the other revisions as "not kept", and opening one explains why. - **Turning it on** records the current state as a new `baseline` revision, with one copy charged to the owner. Later saves are charged what they change. Revisions from while it was off stay unavailable. - **API:** `PATCH /api/timelines/:id/settings` takes `keepHistory`. The response reports `keep_history`, and `history_bytes` (what turning it off would free). The history API marks each revision `available`. ## Decisions on the issue's open questions - **Forks:** allowed. Copies (forks and duplicates) inherit the setting, so a copy of a log keeps no history either until its owner turns it on. - **Sync:** works while the revision a fork last shared with upstream is kept: - always, while upstream keeps history; - for forks made before history was turned off, once more, from the revision kept for them; - otherwise only while upstream hasn't moved. The sync page states the reason up front and disables the button. - **Pull requests:** need saved history on both sides. A timeline without it takes none, and a fork without it can't propose; both pages say so. Pull requests opened before still rebase and merge. One rebased onto a revision that isn't kept shows no change summary afterwards, and says why. - **Grace period:** none. Deletion is immediate, after the confirmation. - **Log tools:** they write to existing timelines, so their docs now recommend turning history off when setting a timeline up. The importer's storage estimate follows the setting. A server-wide default for new timelines isn't included. ## How it works - **Schema:** - `oc_timelines.keep_history`; - a revision may now have no content (no snapshot, patch or rows); - the revision immutability trigger allows exactly one change, forgetting content (`oc_revision_forget`); anything else, including restoring content, is refused; - the storage trigger now also fires on that update, which is how the refund happens. - **Turning it off** (`stopHistory`): forgets the revisions nothing else reads, then `pruneHistoryRows` removes the versions only those revisions saw. The versions kept revisions still see are ended after the latest revision. - **Turning it on** (`startHistory`): uses the existing machinery. The state is copied as it is, or, for a copy whose kept revisions still read through to its base, compared with that base as a whole-timeline save is. - **Migrations** (`startHistory` in `history.mjs`) start no history for timelines without it. - **Editor:** reading the revision it loaded falls back to the current state if that revision isn't kept any more. ## Measurements 200,000 moments, three appends of 5,000 log moments each: | | | |---|--:| | Charged with history (38 MB timeline) | 78 MB | | Charged without | 38 MB | | Turning it off | 1.0 s | | Turning it on again (one copy, as an upgrade makes) | 15 s | | Appending 5,000 moments, with / without history | 4.9–6.9 s / 6.2–7.1 s | Save times showed no measurable difference at this size; the gain is storage. ## Tests - **New `test/optional-history-postgres.mjs`** (ad…
Sources
Open #153 · Let a timeline stop keeping saved history in the timeline