GNU bug report logs -
#72556
29.1.90; vc-diff does not undo hunk in end of source file
Previous Next
Reported by: Tomas Nordin <tomasn <at> posteo.net>
Date: Sat, 10 Aug 2024 12:12:01 UTC
Severity: normal
Found in version 29.1.90
Done: Dmitry Gutov <dmitry <at> gutov.dev>
Bug is archived. No further changes may be made.
To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 72556 in the body.
You can then email your comments to 72556 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
Report forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#72556
; Package
emacs
.
(Sat, 10 Aug 2024 12:12:01 GMT)
Full text and
rfc822 format available.
Acknowledgement sent
to
Tomas Nordin <tomasn <at> posteo.net>
:
New bug report received and forwarded. Copy sent to
bug-gnu-emacs <at> gnu.org
.
(Sat, 10 Aug 2024 12:12:01 GMT)
Full text and
rfc822 format available.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
Hello Emacs
I have got used to the diff-mode feature of undoing hunks. I have
noticed that if the diff hunk is an addition in the end of the source
file, I dont get the expected question if I want to undo the hunk.
Instead, the hunk is applied again.
My example is with a git repo, some edits made (and saved to disk) in a
file, and hitting C-x v = to view the diff. Move to one of the hunks.
One can now diff-apply-hunk to reverse the hunk. But if that hunk is the
last thing in the source file, the hunk is applied (again). This is not
what I expect.
To reproduce:
$ mkdir apply
$ cd apply
$ echo "first line of code" > example.file
$ git init
$ git add .
$ git commit -m 'init'
$ echo "last line of code" >> example.file
$ emacs -Q example.file
C-x v =
n
C-c C-a
The hunk is applied in the source buffer.
In GNU Emacs 29.1.90 (build 1, x86_64-pc-linux-gnu, GTK+ Version
3.24.38, cairo version 1.16.0) of 2023-11-18 built on fliptop2
Repository revision: d9e43f2197fa1d5ade1d483b15cc50c6d705b969
Repository branch: emacs-29
Windowing system distributor 'The X.Org Foundation', version 11.0.12101007
System Description: Debian GNU/Linux 12 (bookworm)
Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG
JSON LCMS2 LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 M17N_FLT MODULES NOTIFY
INOTIFY PDUMPER PNG RSVG SECCOMP SOUND THREADS TIFF TOOLKIT_SCROLL_BARS
WEBP X11 XDBE XIM XINPUT2 XPM GTK3 ZLIB
Important settings:
value of $LC_MONETARY: sv_SE.UTF-8
value of $LC_NUMERIC: sv_SE.UTF-8
value of $LC_TIME: sv_SE.UTF-8
value of $LANG: en_US.UTF-8
value of $XMODIFIERS: @im=ibus
locale-coding-system: utf-8-unix
Major mode: Fundamental
Minor modes in effect:
tooltip-mode: t
global-eldoc-mode: t
show-paren-mode: t
electric-indent-mode: t
mouse-wheel-mode: t
tool-bar-mode: t
menu-bar-mode: t
file-name-shadow-mode: t
global-font-lock-mode: t
font-lock-mode: t
blink-cursor-mode: t
line-number-mode: t
indent-tabs-mode: t
transient-mark-mode: t
auto-composition-mode: t
auto-encryption-mode: t
auto-compression-mode: t
Load-path shadows:
None found.
Features:
(shadow sort mail-extr emacsbug message mailcap yank-media puny dired
dired-loaddefs rfc822 mml mml-sec password-cache epa derived epg rfc6068
epg-config gnus-util text-property-search mm-decode mm-bodies mm-encode
mail-parse rfc2231 mailabbrev gmm-utils mailheader sendmail rfc2047
rfc2045 ietf-drums mm-util mail-prsvr mail-utils time-date subr-x
smerge-mode diff vc vc-git diff-mode easy-mmode vc-dispatcher
cl-loaddefs cl-lib rmc iso-transl tooltip cconv eldoc paren electric
uniquify ediff-hook vc-hooks lisp-float-type elisp-mode mwheel
term/x-win x-win term/common-win x-dnd tool-bar dnd fontset image
regexp-opt fringe tabulated-list replace newcomment text-mode lisp-mode
prog-mode register page tab-bar menu-bar rfn-eshadow isearch easymenu
timer select scroll-bar mouse jit-lock font-lock syntax font-core
term/tty-colors frame minibuffer nadvice seq simple cl-generic
indonesian philippine cham georgian utf-8-lang misc-lang vietnamese
tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek
romanian slovak czech european ethiopic indian cyrillic chinese
composite emoji-zwj charscript charprop case-table epa-hook
jka-cmpr-hook help abbrev obarray oclosure cl-preloaded button loaddefs
theme-loaddefs faces cus-face macroexp files window text-properties
overlay sha1 md5 base64 format env code-pages mule custom widget keymap
hashtable-print-readable backquote threads dbusbind inotify lcms2
dynamic-setting system-font-setting font-render-setting cairo
move-toolbar gtk x-toolkit xinput2 x multi-tty make-network-process
emacs)
Memory information:
((conses 16 44032 13907)
(symbols 48 5959 0)
(strings 32 16246 1269)
(string-bytes 1 466537)
(vectors 16 10894)
(vector-slots 8 165303 14637)
(floats 8 28 20)
(intervals 56 226 0)
(buffers 976 13))
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#72556
; Package
emacs
.
(Sat, 17 Aug 2024 09:40:01 GMT)
Full text and
rfc822 format available.
Message #8 received at 72556 <at> debbugs.gnu.org (full text, mbox):
> From: Tomas Nordin <tomasn <at> posteo.net>
> Date: Sat, 10 Aug 2024 12:11:08 +0000
>
> I have got used to the diff-mode feature of undoing hunks. I have
> noticed that if the diff hunk is an addition in the end of the source
> file, I dont get the expected question if I want to undo the hunk.
> Instead, the hunk is applied again.
>
> My example is with a git repo, some edits made (and saved to disk) in a
> file, and hitting C-x v = to view the diff. Move to one of the hunks.
> One can now diff-apply-hunk to reverse the hunk. But if that hunk is the
> last thing in the source file, the hunk is applied (again). This is not
> what I expect.
>
> To reproduce:
>
> $ mkdir apply
> $ cd apply
> $ echo "first line of code" > example.file
> $ git init
> $ git add .
> $ git commit -m 'init'
> $ echo "last line of code" >> example.file
> $ emacs -Q example.file
>
> C-x v =
> n
> C-c C-a
>
> The hunk is applied in the source buffer.
Juri and Dmitry, any comments or suggestions?
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#72556
; Package
emacs
.
(Mon, 19 Aug 2024 16:51:02 GMT)
Full text and
rfc822 format available.
Message #11 received at 72556 <at> debbugs.gnu.org (full text, mbox):
>> To reproduce:
>>
>> $ mkdir apply
>> $ cd apply
>> $ echo "first line of code" > example.file
>> $ git init
>> $ git add .
>> $ git commit -m 'init'
>> $ echo "last line of code" >> example.file
>> $ emacs -Q example.file
>>
>> C-x v =
>> n
>> C-c C-a
>>
>> The hunk is applied in the source buffer.
>
> Juri and Dmitry, any comments or suggestions?
I don't know why it fails at the end, so I tried to debug 'diff-apply-hunk',
and found that the problem is in these lines of 'diff-find-source-location':
;; FIXME: Check for case where both OLD and NEW are found.
(pos (or (diff-find-text (car old))
When the hunk is at the beginning/end of the diff buffer,
then it misses the top/bottom part of the context,
so 'diff-find-text' wrongly matches it because it fails
to see any changes in it due to insufficient context,
and returns switched=nil.
A possible solution would be to add a condition to detect the case
when the hunk is at the beginning/end of the diff buffer.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#72556
; Package
emacs
.
(Sat, 31 Aug 2024 08:11:02 GMT)
Full text and
rfc822 format available.
Message #14 received at 72556 <at> debbugs.gnu.org (full text, mbox):
> From: Juri Linkov <juri <at> linkov.net>
> Cc: Tomas Nordin <tomasn <at> posteo.net>, Dmitry Gutov <dmitry <at> gutov.dev>,
> 72556 <at> debbugs.gnu.org
> Date: Mon, 19 Aug 2024 19:49:05 +0300
>
> >> To reproduce:
> >>
> >> $ mkdir apply
> >> $ cd apply
> >> $ echo "first line of code" > example.file
> >> $ git init
> >> $ git add .
> >> $ git commit -m 'init'
> >> $ echo "last line of code" >> example.file
> >> $ emacs -Q example.file
> >>
> >> C-x v =
> >> n
> >> C-c C-a
> >>
> >> The hunk is applied in the source buffer.
> >
> > Juri and Dmitry, any comments or suggestions?
>
> I don't know why it fails at the end, so I tried to debug 'diff-apply-hunk',
> and found that the problem is in these lines of 'diff-find-source-location':
>
> ;; FIXME: Check for case where both OLD and NEW are found.
> (pos (or (diff-find-text (car old))
>
> When the hunk is at the beginning/end of the diff buffer,
> then it misses the top/bottom part of the context,
> so 'diff-find-text' wrongly matches it because it fails
> to see any changes in it due to insufficient context,
> and returns switched=nil.
>
> A possible solution would be to add a condition to detect the case
> when the hunk is at the beginning/end of the diff buffer.
Thanks. Would anyone like to submit a patch along these lines?
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#72556
; Package
emacs
.
(Sat, 14 Sep 2024 07:36:01 GMT)
Full text and
rfc822 format available.
Message #17 received at 72556 <at> debbugs.gnu.org (full text, mbox):
Ping! Would someone want to work on a patch, or should I close this
bug as wontfix?
> Cc: 72556 <at> debbugs.gnu.org
> Date: Sat, 31 Aug 2024 11:09:36 +0300
> From: Eli Zaretskii <eliz <at> gnu.org>
>
> > From: Juri Linkov <juri <at> linkov.net>
> > Cc: Tomas Nordin <tomasn <at> posteo.net>, Dmitry Gutov <dmitry <at> gutov.dev>,
> > 72556 <at> debbugs.gnu.org
> > Date: Mon, 19 Aug 2024 19:49:05 +0300
> >
> > >> To reproduce:
> > >>
> > >> $ mkdir apply
> > >> $ cd apply
> > >> $ echo "first line of code" > example.file
> > >> $ git init
> > >> $ git add .
> > >> $ git commit -m 'init'
> > >> $ echo "last line of code" >> example.file
> > >> $ emacs -Q example.file
> > >>
> > >> C-x v =
> > >> n
> > >> C-c C-a
> > >>
> > >> The hunk is applied in the source buffer.
> > >
> > > Juri and Dmitry, any comments or suggestions?
> >
> > I don't know why it fails at the end, so I tried to debug 'diff-apply-hunk',
> > and found that the problem is in these lines of 'diff-find-source-location':
> >
> > ;; FIXME: Check for case where both OLD and NEW are found.
> > (pos (or (diff-find-text (car old))
> >
> > When the hunk is at the beginning/end of the diff buffer,
> > then it misses the top/bottom part of the context,
> > so 'diff-find-text' wrongly matches it because it fails
> > to see any changes in it due to insufficient context,
> > and returns switched=nil.
> >
> > A possible solution would be to add a condition to detect the case
> > when the hunk is at the beginning/end of the diff buffer.
>
> Thanks. Would anyone like to submit a patch along these lines?
>
>
>
>
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#72556
; Package
emacs
.
(Sat, 14 Sep 2024 15:49:01 GMT)
Full text and
rfc822 format available.
Message #20 received at 72556 <at> debbugs.gnu.org (full text, mbox):
On 19/08/2024 19:49, Juri Linkov wrote:
> A possible solution would be to add a condition to detect the case
> when the hunk is at the beginning/end of the diff buffer.
This might have drawbacks. Sometimes we want to split a hunk and then
apply the top part. And when a hunk is split, the top part can't have
context at the end.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#72556
; Package
emacs
.
(Sat, 14 Sep 2024 15:51:01 GMT)
Full text and
rfc822 format available.
Message #23 received at 72556 <at> debbugs.gnu.org (full text, mbox):
Hi!
On 10/08/2024 15:11, Tomas Nordin wrote:
> I have
> noticed that if the diff hunk is an addition in the end of the source
> file, I dont get the expected question if I want to undo the hunk.
> Instead, the hunk is applied again.
No matter the resolution of this bug, just wanted to make sure you know
that you can force the reverse direction by adding the prefix to the
command.
So while 'C-c C-a' applies the hunk, 'C-u C-c C-a' reverses it (with a
similar check that sees whether the hunk has been applied already).
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#72556
; Package
emacs
.
(Sun, 15 Sep 2024 10:43:02 GMT)
Full text and
rfc822 format available.
Message #26 received at 72556 <at> debbugs.gnu.org (full text, mbox):
Dmitry Gutov <dmitry <at> gutov.dev> writes:
> Hi!
>
> On 10/08/2024 15:11, Tomas Nordin wrote:
>> I have
>> noticed that if the diff hunk is an addition in the end of the source
>> file, I dont get the expected question if I want to undo the hunk.
>> Instead, the hunk is applied again.
>
> No matter the resolution of this bug, just wanted to make sure you know
> that you can force the reverse direction by adding the prefix to the
> command.
>
> So while 'C-c C-a' applies the hunk, 'C-u C-c C-a' reverses it (with a
> similar check that sees whether the hunk has been applied already).
I was loosely aware of that but never got it into my fingers. Instead I
was relying on that dwim behavior of diff-mode. But trying the prefix
variant out, it seems to be a solid way of "un-applying" a hunk.
Might not be worth the trouble to try and fix this problem if it is
complicated. There is a solid way to do what I want (which is maybe the
proper way), and my complaint about this is the only one I have seen. A
wont-fix is fine with me.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#72556
; Package
emacs
.
(Sat, 01 Mar 2025 14:29:02 GMT)
Full text and
rfc822 format available.
Message #29 received at 72556 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Juri Linkov <juri <at> linkov.net> writes:
>> Juri and Dmitry, any comments or suggestions?
>
> I don't know why it fails at the end, so I tried to debug 'diff-apply-hunk',
> and found that the problem is in these lines of 'diff-find-source-location':
>
> ;; FIXME: Check for case where both OLD and NEW are found.
> (pos (or (diff-find-text (car old))
>
> When the hunk is at the beginning/end of the diff buffer,
> then it misses the top/bottom part of the context,
> so 'diff-find-text' wrongly matches it because it fails
> to see any changes in it due to insufficient context,
> and returns switched=nil.
Here is some notes from a bug-hunt (mabye a glorified variant of what
you are already saying Juri). Perspective is from
'diff-find-source-location' in diff-mode.el
The call (diff-find-text (car old)):
OLD is text derived from hunk representing text in the source file
before the edits. => nil if not found in the source file
The call (diff-find-text (car new)):
NEW is text derived from hunk representing text in the source file
after the edits. => nil if not found in the source file
Assumptions made on result from applying 'diff-find-text' on
NEW: if non-nil, hunk is already applied
OLD: if non-nil, hunk is not applied
When the edited line(s) have context only above or below itself in the
hunk, the application of diff-find-text on OLD will always yield
non-nil, because OLD is then always found in the source file.
The application of diff-find-text on NEW shouldn't have similar
problems.
There is a comment requesting a fix for when both OLD and NEW are
found. Maybe this was the case concerned.
The variable SWITCHED, then, should be non-nil when hunk is already
applied, and is a prerequisite for the DWIM behavior to work (the
bug). It is not set to t when 'diff-find-text' is applied on OLD (the
first or:ed attempt), which returns non-nil.
The attached patch of diff-mode.el makes the assumption that hunk is
already applied when both OLD and NEW yields non-nil, and checks if
this is the case as the first or:ed attempt. Optimistically assumes
that this was the requested FIXME and so removes the FIXME comment.
Dmitri had concerns about drawbacks when splitting a hunk. I don't have
successful experience of that operation. Can Dmitri maybe check so that
this patch don't produce such drawbacks?
[0001-Fix-detection-of-hunk-already-applied.patch (text/x-diff, attachment)]
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#72556
; Package
emacs
.
(Sat, 01 Mar 2025 19:30:02 GMT)
Full text and
rfc822 format available.
Message #32 received at 72556 <at> debbugs.gnu.org (full text, mbox):
Tomas Nordin <tomasn <at> posteo.net> writes:
> The attached patch of diff-mode.el makes the assumption that hunk is
> already applied when both OLD and NEW yields non-nil, and checks if
> this is the case as the first or:ed attempt. Optimistically assumes
> that this was the requested FIXME and so removes the FIXME comment.
But the patch seem to break the technique suggested by Dmitri,
'C-u C-c C-a', so I missed something. I will see if I can find
some other fix.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#72556
; Package
emacs
.
(Sat, 01 Mar 2025 21:22:02 GMT)
Full text and
rfc822 format available.
Message #35 received at 72556 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Tomas Nordin <tomasn <at> posteo.net> writes:
[...]
> NEW: if non-nil, hunk is already applied
> OLD: if non-nil, hunk is not applied
Those notes might be correct for the normal case but when REVERSE is
non-nil, the notion of NEW and OLD is reversed.
[...]
So I added a check to only satisfy the NEW *and* OLD case when REVERSE is
not given. What do you think? (Also aligned the leading whitespace
with original code). In my manual tests it seems to work. I learned
about the splitting of hunks and it doesn't seem broken.
[0001-Fix-detection-of-hunk-already-applied.patch (text/x-diff, attachment)]
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#72556
; Package
emacs
.
(Tue, 11 Mar 2025 07:43:02 GMT)
Full text and
rfc822 format available.
Message #38 received at 72556 <at> debbugs.gnu.org (full text, mbox):
> So I added a check to only satisfy the NEW *and* OLD case when REVERSE is
> not given. What do you think? (Also aligned the leading whitespace
> with original code). In my manual tests it seems to work. I learned
> about the splitting of hunks and it doesn't seem broken.
If Dmitry agrees then let's push this patch.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#72556
; Package
emacs
.
(Tue, 11 Mar 2025 22:34:01 GMT)
Full text and
rfc822 format available.
Message #41 received at 72556 <at> debbugs.gnu.org (full text, mbox):
Juri Linkov <juri <at> linkov.net> writes:
>> So I added a check to only satisfy the NEW *and* OLD case when REVERSE is
>> not given. What do you think? (Also aligned the leading whitespace
>> with original code). In my manual tests it seems to work. I learned
>> about the splitting of hunks and it doesn't seem broken.
>
> If Dmitry agrees then let's push this patch.
In the meantime I wrote two test cases in
test/lisp/vc/diff-mode-tests.el, one for a topmost and one for a
bottommost addition. They both fail before the patch but pass after it.
Maybe I could present them here as an attached patch as well?
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#72556
; Package
emacs
.
(Tue, 11 Mar 2025 22:43:01 GMT)
Full text and
rfc822 format available.
Message #44 received at 72556 <at> debbugs.gnu.org (full text, mbox):
On 12/03/2025 00:33, Tomas Nordin wrote:
> In the meantime I wrote two test cases in
> test/lisp/vc/diff-mode-tests.el, one for a topmost and one for a
> bottommost addition. They both fail before the patch but pass after it.
> Maybe I could present them here as an attached patch as well?
Yes, please!
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#72556
; Package
emacs
.
(Wed, 12 Mar 2025 22:21:02 GMT)
Full text and
rfc822 format available.
Message #47 received at 72556 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Dmitry Gutov <dmitry <at> gutov.dev> writes:
> On 12/03/2025 00:33, Tomas Nordin wrote:
>> In the meantime I wrote two test cases in
>> test/lisp/vc/diff-mode-tests.el, one for a topmost and one for a
>> bottommost addition. They both fail before the patch but pass after it.
>> Maybe I could present them here as an attached patch as well?
>
> Yes, please!
Here it is, on top of todays master
[0001-Tests-for-diff-mode-undos.patch (text/x-diff, attachment)]
Reply sent
to
Dmitry Gutov <dmitry <at> gutov.dev>
:
You have taken responsibility.
(Sat, 15 Mar 2025 03:11:02 GMT)
Full text and
rfc822 format available.
Notification sent
to
Tomas Nordin <tomasn <at> posteo.net>
:
bug acknowledged by developer.
(Sat, 15 Mar 2025 03:11:02 GMT)
Full text and
rfc822 format available.
Message #52 received at 72556-done <at> debbugs.gnu.org (full text, mbox):
Version 31.1
On 13/03/2025 00:19, Tomas Nordin wrote:
> Here it is, on top of todays master
Thank you, I've pushed the combined patch to the master branch:
https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=4980287e081d3efd29f64973938ca2a0575f521e
Any further improvements to the diff-mode tests would be welcome too -
such as similar test case(s) for deletion hunks and/or extracting the
common part of the new test cases into a macro.
This report meanwhile seems resolved.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#72556
; Package
emacs
.
(Sat, 15 Mar 2025 12:52:01 GMT)
Full text and
rfc822 format available.
Message #55 received at 72556-done <at> debbugs.gnu.org (full text, mbox):
Dmitry Gutov <dmitry <at> gutov.dev> writes:
> Version 31.1
>
> On 13/03/2025 00:19, Tomas Nordin wrote:
>
>> Here it is, on top of todays master
>
> Thank you, I've pushed the combined patch to the master branch:
Let's hope it holds.
> Any further improvements to the diff-mode tests would be welcome too -
> such as similar test case(s) for deletion hunks and/or extracting the
> common part of the new test cases into a macro.
Thanks for the nudge. I understand it as adding tests for deletion of
hunks in patch buffers, plus try to make some macro(s) to avoid
repeating code patterns in test cases.? I can probably try that some
time.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#72556
; Package
emacs
.
(Sat, 15 Mar 2025 13:26:03 GMT)
Full text and
rfc822 format available.
Message #58 received at 72556-done <at> debbugs.gnu.org (full text, mbox):
On 15/03/2025 14:50, Tomas Nordin wrote:
> I understand it as adding tests for deletion of
> hunks in patch buffers, plus try to make some macro(s) to avoid
> repeating code patterns in test cases.? I can probably try that some
> time.
Yup. Thanks!
bug archived.
Request was from
Debbugs Internal Request <help-debbugs <at> gnu.org>
to
internal_control <at> debbugs.gnu.org
.
(Sun, 13 Apr 2025 11:24:56 GMT)
Full text and
rfc822 format available.
This bug report was last modified 65 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.