| #
6d10fb86
|
| 14-Jul-2026 |
Andreas Gohr <gohr@cosmocode.de> |
style(changelog): fix overlong line
|
| #
6f10c544
|
| 08-Jul-2026 |
Andreas Gohr <gohr@cosmocode.de> |
chore(changelog): rename $clogRev to $recordedRev
It's a bit easier to decipher
|
| #
5a285deb
|
| 06-Jul-2026 |
Andreas Gohr <gohr@cosmocode.de> |
fix(changelog): stop media mtime bumps from recording bogus external edits
Commit 01e8d739c ("persist external-edit detection on first read") began writing detected external edits to the changelog a
fix(changelog): stop media mtime bumps from recording bogus external edits
Commit 01e8d739c ("persist external-edit detection on first read") began writing detected external edits to the changelog and snapshotting the new content to the attic via saveExternalAttic(). That is correct for pages, which archive every revision, but wrong for media: a media file's current revision is never archived (media only copies content to the attic on replace or delete, to save space).
So getCurrentRevisionInfo()'s external-change detection had no attic copy of the current revision to work with: the unchanged-content guard always failed and the old-size lookup returned 0. A mere mtime bump (touch, rsync --times, unzip) of an unchanged media file was therefore recorded as an external edit sized as the whole file, and since detection is now persisted, that bogus entry (plus a redundant attic copy) became permanent.
The "before" size of an external change is now taken through a lastRevisionSize() seam: the base reads it from the last revision's attic copy (unchanged for pages), and MediaChangeLog reconstructs it from the previous revision's archived size plus the size change logged for the last revision. currentContentMatchesRevision() compares the current file size against that reconstructed size, so an unchanged size is treated as a mere touch (mtime reset, no entry) and a changed size is a real external edit with the correct size change.
Media no longer snapshots an external edit to the attic at all, consistent with not archiving the current revision: it will be archived if and when the file is later replaced. The mtime repair for an unreliable external date moved to a base repairExternalMtime() shared by pages and media.
show more ...
|
| #
6372bc80
|
| 06-Jul-2026 |
Andreas Gohr <gohr@cosmocode.de> |
fix(changelog): detect an externally restored deleted page as a re-creation
A deleted page restored outside DokuWiki with a preserved mtime predating the deletion (cp -p from an old backup, rsync --
fix(changelog): detect an externally restored deleted page as a re-creation
A deleted page restored outside DokuWiki with a preserved mtime predating the deletion (cp -p from an old backup, rsync --times) has content matching the delete revision's attic copy. That copy holds the pre-delete content, so the unchanged-content shortcut in getCurrentRevisionInfo() wrongly treated the restore as an unchanged file, touched the mtime back to the delete revision and kept the DELETE as the current revision. The page then stayed "deleted" on every subsequent read.
A last recorded revision of type DELETE means the page did not exist then, so an existing file is an external re-creation regardless of its mtime. getCurrentRevisionInfo() now classifies the external change and delegates to synthesizeExternalDeletion/synthesizeExternalCreate/synthesizeExternalEdit; only the edit path keeps the unchanged-content shortcut. A re-creation records the full file as its size change and, when the restored mtime predates the delete, is dated just after it with an unknown date.
The getCurrentRevisionInfo() method got rather unwieldy, so it was refactored to use three helper methods, for synthesizing the changelog data.
show more ...
|
| #
eab6268c
|
| 07-Jun-2026 |
Andreas Gohr <andi@splitbrain.org> |
fix(changelog): keep out-of-order external edits out of recent changes (#4634)
A detected external edit is recorded both in the page's own changelog and in the global recent-changes feed. When its d
fix(changelog): keep out-of-order external edits out of recent changes (#4634)
A detected external edit is recorded both in the page's own changelog and in the global recent-changes feed. When its date is older than the most recent change already in the global changelog — an old file surfacing after the feed has moved on — appending it placed it at the top of recent changes with an old date, above genuinely newer entries.
writeLogEntry() now delegates the global-feed append to writeGlobalLogEntry(), which skips an external edit whose date predates the global changelog's last-modified time. The entry still lands in the page's own changelog; it is only kept out of the cross-page feed. Normal edits are always appended.
show more ...
|
| #
0a245329
|
| 07-Jun-2026 |
Andreas Gohr <andi@splitbrain.org> |
fix(changelog): don't record an external edit when the content is unchanged (#4634)
A current revision's file mtime can change without its content changing — a backup restore, a git checkout, an in-
fix(changelog): don't record an external edit when the content is unchanged (#4634)
A current revision's file mtime can change without its content changing — a backup restore, a git checkout, an in-place rewrite. Such a bump was detected as an external edit and logged with a 0-byte size change, cluttering history.
getCurrentRevisionInfo() now compares the current content against the last recorded revision before treating an mtime change as an external edit. When the content is identical no external edit happened: the file mtime is reset to the recorded revision date and the last revision is returned. The comparison is an abstract currentContentMatchesRevision() — pages compare the decompressed text, media compare file size then md5_file().
show more ...
|
| #
8788dbbd
|
| 06-May-2026 |
splitbrain <86426+splitbrain@users.noreply.github.com> |
Rector and PHPCS fixes
|
| #
01e8d739
|
| 25-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
refactor(changelog): persist external-edit detection on first read
This addresses the flaky test that makes tests randomly fail (mostly on windows runners).
The flake in common_saveWikiText_test::t
refactor(changelog): persist external-edit detection on first read
This addresses the flaky test that makes tests randomly fail (mostly on windows runners).
The flake in common_saveWikiText_test::test_savesequence5 came from this line in ChangeLog::getCurrentRevisionInfo():
'date' => max($lastRev + 1, time() - 1)
The synthesized "external delete" entry was kept in memory only and only persisted later, when saveWikiText next called detectExternalEdit. That meant the formula was evaluated twice on different ChangeLog instances — once during the test's inspection, and again during the following saveWikiText — and the two evaluations could pick different seconds depending on how long the surrounding I/O took. The test cached the first result in $expectExternal and asserted it against the on-disk entry written during the second call. On the slower Windows runner the second call sometimes crossed a second boundary, producing the off-by-one date mismatch.
The questions I had was, why are we persisting external file deletions (or edits) only when a page is saved when we are obviously already detecting it earlier during the changelog read already?
Instead of recording the external delete at the time a new page is written, it makes sense to record it as soon as we detect it (when the changelog is requested by a user or a bot). This will make the recoded timestamp closer to the actual deletion.
This patch refactors the changelog accordingly, but still tries to be minimal invasive (I think the changelog handling would need much more refactoring, but that's beyond the scope of this change).
To enable proper locking (when logging an external edit and copying the attic file), locking had to be moved to the Changelog class, duplicating some code of io_saveFile.
PageFile::detectExternalEdit() and the deprecated procedural wrapper detectExternalEdit() in inc/common.php are removed. A codesearch.dokuwiki.org check confirmed no plugin calls the method directly; the only external caller of the procedural function is the farmsync plugin, which needs a parallel update.
show more ...
|
| #
d41f5a8f
|
| 07-Mar-2026 |
Andreas Gohr <andi@splitbrain.org> |
fix destructuring false returns from changelog functions
The changelog functions can return false when lines are unparsable or don't exist. The result can no longer be destructured then in newer PHP
fix destructuring false returns from changelog functions
The changelog functions can return false when lines are unparsable or don't exist. The result can no longer be destructured then in newer PHP versions. This adds the necessary checks.
It should also handle corrupt lines within a changelog better.
show more ...
|
| #
4d95c168
|
| 24-Sep-2023 |
Gerrit Uitslag <klapinklapin@gmail.com> |
code style
|
| #
85160059
|
| 24-Sep-2023 |
Gerrit Uitslag <klapinklapin@gmail.com> |
little refactoring
|
| #
a835c93a
|
| 24-Sep-2023 |
Gerrit Uitslag <klapinklapin@gmail.com> |
Let ChangeLog set the mode(media/page) for a revision log entry
|
| #
0f8604a9
|
| 02-Sep-2023 |
Andreas Gohr <andi@splitbrain.org> |
don't strict compare
I'm not 100% sure but revs might be strings sometimes, so better not chage current behavior
|
| #
90fb952c
|
| 31-Aug-2023 |
Andreas Gohr <andi@splitbrain.org> |
code style: operator spacing
|
| #
7d34963b
|
| 31-Aug-2023 |
Andreas Gohr <andi@splitbrain.org> |
coding style: control flow line breaks
|
| #
177d6836
|
| 31-Aug-2023 |
Andreas Gohr <andi@splitbrain.org> |
coding style: control flow whitespaces
|
| #
83bec475
|
| 31-Aug-2023 |
Andreas Gohr <andi@splitbrain.org> |
fix abstract declaration of ChangeLog::getFilename()
|
| #
6e695190
|
| 29-Aug-2023 |
Andreas Gohr <andi@splitbrain.org> |
fix sizehandling in Changelog
Seems rector was too aggressive here in removing a variable.
|
| #
0603e565
|
| 29-Aug-2023 |
Andreas Gohr <andi@splitbrain.org> |
Apply rector fixes to inc/ChangeLog
|
| #
aec2ae89
|
| 24-Jun-2022 |
Andreas Gohr <andi@splitbrain.org> |
Merge pull request #3607 from ssahara/revdiff2
add mechanism to track current revision, and other code improvements
|
| #
10f359ad
|
| 28-Apr-2022 |
Andreas Gohr <andi@splitbrain.org> |
Replace direct calls to strftime with dformat calls
This is in preparation for fixing #3573
|
| #
eeda7ada
|
| 23-Jan-2022 |
Gerrit Uitslag <klapinklapin@gmail.com> |
some spelling
|
| #
a19054e9
|
| 23-Jan-2022 |
Satoshi Sahara <sahara.satoshi@gmail.com> |
fix typo
|
| #
312e7095
|
| 23-Jan-2022 |
Satoshi Sahara <sahara.satoshi@gmail.com> |
add mechanism to track external current revision
|
| #
86216bf0
|
| 06-Jan-2022 |
Gerrit Uitslag <klapinklapin@gmail.com> |
Move caching current revision info to getRevisionInfo()
needed to ensure initiation of the class is not using files from disk. Because getCurrentRevisionInfo needs getRevisionInfo() as well, looping
Move caching current revision info to getRevisionInfo()
needed to ensure initiation of the class is not using files from disk. Because getCurrentRevisionInfo needs getRevisionInfo() as well, looping needs to be prevented
show more ...
|