aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Nordin2025-03-15 04:08:47 +0200
committerDmitry Gutov2025-03-15 04:54:11 +0200
commit4980287e081d3efd29f64973938ca2a0575f521e (patch)
tree1c4d526bf6552abd4257b627d659e112c84553d3
parentaf5a75a0bdd891686c67648bc0fa09ffb7e3ed0d (diff)
downloademacs-4980287e081d3efd29f64973938ca2a0575f521e.tar.gz
emacs-4980287e081d3efd29f64973938ca2a0575f521e.zip
Teach diff-apply-hunk to handle hunks with empty context
* lisp/vc/diff-mode.el (diff-find-source-location): Consider the case when there is no diff context above or below edited lines. (bug#72556) * test/lisp/vc/diff-mode-tests.el: Add tests for undoing hunks from diffs with addtions only in the beginning or end of the source file.
-rw-r--r--lisp/vc/diff-mode.el8
-rw-r--r--test/lisp/vc/diff-mode-tests.el96
2 files changed, 101 insertions, 3 deletions
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index a99487b0370..459154f534b 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -2048,9 +2048,11 @@ SWITCHED is non-nil if the patch is already applied."
2048 (goto-char (point-min)) (forward-line (1- (string-to-number line))) 2048 (goto-char (point-min)) (forward-line (1- (string-to-number line)))
2049 (let* ((orig-pos (point)) 2049 (let* ((orig-pos (point))
2050 (switched nil) 2050 (switched nil)
2051 ;; FIXME: Check for case where both OLD and NEW are found. 2051 (maybe-old (diff-find-text (car old)))
2052 (pos (or (diff-find-text (car old)) 2052 (maybe-new (diff-find-text (car new)))
2053 (progn (setq switched t) (diff-find-text (car new))) 2053 (pos (or (and maybe-new maybe-old (null reverse) (setq switched t) maybe-new)
2054 maybe-old
2055 (progn (setq switched t) maybe-new)
2054 (progn (setq switched nil) 2056 (progn (setq switched nil)
2055 (condition-case nil 2057 (condition-case nil
2056 (diff-find-approx-text (car old)) 2058 (diff-find-approx-text (car old))
diff --git a/test/lisp/vc/diff-mode-tests.el b/test/lisp/vc/diff-mode-tests.el
index bbd66824e48..5611e9abc79 100644
--- a/test/lisp/vc/diff-mode-tests.el
+++ b/test/lisp/vc/diff-mode-tests.el
@@ -597,5 +597,101 @@ baz"))))
597 (should (eq (get-text-property (match-beginning 0) 'face) 597 (should (eq (get-text-property (match-beginning 0) 'face)
598 'diff-context))))) 598 'diff-context)))))
599 599
600(ert-deftest diff-mode-test-topmost-addition-undo ()
601 (let ((patch "diff --git a/fruits b/fruits
602index 0dcecd3..d0eb2e7 100644
603--- a/fruits
604+++ b/fruits
605@@ -1,2 +1,3 @@
606+fruits
607 apple
608 orange
609")
610 (text-before "apple
611orange
612")
613 (text-after "fruits
614apple
615orange
616"))
617 (ert-with-temp-directory temp-dir
618 (let ((buf-after
619 (find-file-noselect (format "%s/%s" temp-dir "fruits"))))
620 (cd temp-dir)
621
622 (with-current-buffer buf-after (insert text-after) (save-buffer))
623 (with-temp-buffer
624 (insert patch)
625 (goto-char (point-min))
626 (diff-hunk-next)
627 ;; Undo hunk by non-nil REVERSE argument (C-u C-c C-a)
628 (diff-apply-hunk t))
629 (with-current-buffer buf-after
630 (should (string-equal (buffer-string) text-before)))
631
632 (with-current-buffer buf-after
633 (erase-buffer) (insert text-after) (save-buffer))
634 (with-temp-buffer
635 (insert patch)
636 (goto-char (point-min))
637 (diff-hunk-next)
638 ;; Undo hunk by dwim behaviour
639 (cl-letf (((symbol-function 'y-or-n-p) #'always))
640 (diff-apply-hunk)))
641 (with-current-buffer buf-after
642 (should (string-equal (buffer-string) text-before)))
643
644 (with-current-buffer buf-after
645 (set-buffer-modified-p nil)
646 (kill-buffer buf-after))))))
647
648(ert-deftest diff-mode-test-bottommost-addition-undo ()
649 (let ((patch "diff --git a/fruits b/fruits
650index 0dcecd3..6f210ff 100644
651--- a/fruits
652+++ b/fruits
653@@ -1,2 +1,3 @@
654 apple
655 orange
656+plum
657")
658 (text-before "apple
659orange
660")
661 (text-after "apple
662orange
663plum
664"))
665 (ert-with-temp-directory temp-dir
666 (let ((buf-after
667 (find-file-noselect (format "%s/%s" temp-dir "fruits"))))
668 (cd temp-dir)
669
670 (with-current-buffer buf-after (insert text-after) (save-buffer))
671 (with-temp-buffer
672 (insert patch)
673 (goto-char (point-min))
674 (diff-hunk-next)
675 ;; Undo hunk by non-nil REVERSE argument (C-u C-c C-a)
676 (diff-apply-hunk t))
677 (with-current-buffer buf-after
678 (should (string-equal (buffer-string) text-before)))
679
680 (with-current-buffer buf-after
681 (erase-buffer) (insert text-after) (save-buffer))
682 (with-temp-buffer
683 (insert patch)
684 (goto-char (point-min))
685 (diff-hunk-next)
686 ;; Undo hunk by dwim behaviour
687 (cl-letf (((symbol-function 'y-or-n-p) #'always))
688 (diff-apply-hunk)))
689 (with-current-buffer buf-after
690 (should (string-equal (buffer-string) text-before)))
691
692 (with-current-buffer buf-after
693 (set-buffer-modified-p nil)
694 (kill-buffer buf-after))))))
695
600(provide 'diff-mode-tests) 696(provide 'diff-mode-tests)
601;;; diff-mode-tests.el ends here 697;;; diff-mode-tests.el ends here