Subject: bug#60467: 30.0.50; primitive-undo: Changes to be undone by function different from announced

From: Eli Zaretskii <[email-masked]>
Date: Sun, 01 Jan 2023 16:38:52 +0200

> From: Ihor Radchenko <[email-masked]>
> Date: Sun, 01 Jan 2023 13:40:08 +0000
> 
> 1. Create /tmp/bug.org with the following contents
> 
> * h1
> ** h2
> 
> 2. emacs -Q /tmp/bug.org
> 3. Move point to h2
> 4. M-x org-promote-subtree
> 5. M-x undo
> 6. Observe "Changes to be undone by function different from announced" error

The error message text is confusing, what it wants to say is this:

  Changes undone by a function are different from the announced ones

The problem is here:

                   (apply fun args) ;; Use `save-current-buffer'?
                   ;; Check that the function did what the entry
                   ;; said it would do.
                   (unless (and (= start start-mark)
                                (= (+ delta end) end-mark))  <<<<<<<<<<<<<<<
                     (error "Changes to be undone by function different from announced"))

After re-inserting the deleted string "** " with its face information,
'end-marker' is shifted by 3 position, and is now at buffer position
13, whereas 'end' is still 10 and 'delta' is 1, so their sum is 11.

Also note that if you begin from an empty Org buffer and insert the
initial text "* h1\n** h2\n", and then run the recipe, the problem
doesn't happen, because the "* " part is deleted before "apply fun"
returns, and then 'end-mark' is in its expected position 11.

Adding Stefan, in case how might have ideas for what is wrong here.

This problem exists also in Emacs 29.