diff options
| author | Tomas Nordin | 2025-03-15 04:08:47 +0200 |
|---|---|---|
| committer | Dmitry Gutov | 2025-03-15 04:54:11 +0200 |
| commit | 4980287e081d3efd29f64973938ca2a0575f521e (patch) | |
| tree | 1c4d526bf6552abd4257b627d659e112c84553d3 | |
| parent | af5a75a0bdd891686c67648bc0fa09ffb7e3ed0d (diff) | |
| download | emacs-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.el | 8 | ||||
| -rw-r--r-- | test/lisp/vc/diff-mode-tests.el | 96 |
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 | ||
| 602 | index 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 | ||
| 611 | orange | ||
| 612 | ") | ||
| 613 | (text-after "fruits | ||
| 614 | apple | ||
| 615 | orange | ||
| 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 | ||
| 650 | index 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 | ||
| 659 | orange | ||
| 660 | ") | ||
| 661 | (text-after "apple | ||
| 662 | orange | ||
| 663 | plum | ||
| 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 |