--- /dev/null
+<?php
+
+use BookStack\Entities\Models\Page;
+use BookStack\Facades\Theme;
+use Illuminate\Console\Command;
+use Illuminate\Database\Eloquent\Builder;
+
+// Define the command we want to add to BookStack
+class PruneRevisionsCommand extends Command
+{
+ // Specify how the command should be called, and the description that'll show for it
+ protected $signature = 'bookstack:prune-revisions {bookslug} {pageslug}';
+ protected $description = 'Remove revisions without changelog and reset numbers for a specific page';
+
+ // Define the function that'll be called when the command is performed
+ public function handle(): int
+ {
+ $pageSlug = $this->argument('pageslug');
+ $bookSlug = $this->argument('bookslug');
+
+ // Find the provided page using slugs
+ $page = Page::query()->whereHas('book', function (Builder $query) use ($bookSlug) {
+ $query->where('slug', '=', $bookSlug);
+ })->where('slug', '=', $pageSlug)->first();
+
+ // Return as an error if the page is not found
+ if (!$page) {
+ $this->error("Page of slugs {$bookSlug}:{$pageSlug} not found");
+ return 1;
+ }
+
+ // Delete revisions without changelog, except if it's the current revision
+ $currentRevision = $page->currentRevision()->first();
+ $deleteCount = $page->allRevisions()
+ ->where('type', '=', 'version')
+ ->where('summary', '=', '')
+ ->where('id', '!=', $currentRevision->id)
+ ->delete();
+
+ // Reset numbers on the revisions
+ $revisions = $page->allRevisions()->where('type', '=', 'version')
+ ->orderBy('created_at', 'asc')
+ ->get()
+ ->all();
+ foreach ($revisions as $index => $revision) {
+ $revision->revision_number = $index + 1;
+ $revision->save();
+ }
+
+ // Update page revision count
+ $page->revision_count = count($revisions);
+ $page->save();
+
+ $this->line("Revisions pruned and re-numbered for page [{$page->name}] with {$deleteCount} revisions deleted");
+
+ return 0;
+ }
+}
+
+// Register our command via the theme system
+Theme::registerCommand(new PruneRevisionsCommand());
--- /dev/null
++++
+title = "Prune Revisions Command"
+author = "@ssddanbrown"
+date = 2024-05-23T13:00:00Z
+updated = 2024-05-23T13:00:00Z
+tested = "v24.05.1"
++++
+
+This hack registers a custom command using the logical theme system, which will prune the revisions of a specific page
+to just those with a changelog provided (in addition to the current revision), before resetting the revision numbers
+across the remaining versions to be sequential without gaps. This will also reset the overall revision count on the page.
+
+Once added, the command can be called like so from your BookStack install directory:
+
+```bash
+# Format
+php artisan bookstack:prune-revisions {book-slug} {page-slug}
+
+# Example
+php artisan bookstack:prune-revisions team-notes code-snippets
+```
+
+#### Considerations
+
+- The changes here will not be reflected in activity/audit logs, and existing related activity/audit logs will not be modified.
+- This can delete data with no option to restore without resorting to backups.
+- This could affect other features or processes that may potentially reference specific page revisions or numbers.
+
+#### Code
+
+{{<hack file="functions.php" type="logical">}}