aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Certner2022-11-10 18:57:27 +0100
committerEli Zaretskii2022-11-17 11:40:09 +0200
commitc8b9922e26a42db46411d1dea4e78089adf6743e (patch)
treefd6707ccbf81b9acd4507590d00e3376904d5b12
parenta0ee57c80dea105ab08aad3c0cdce11e43b5fa29 (diff)
downloademacs-c8b9922e26a42db46411d1dea4e78089adf6743e.tar.gz
emacs-c8b9922e26a42db46411d1dea4e78089adf6743e.zip
ediff: Merges with ancestor: Fix computation of hunks and proposed merge
Hunks were not computed correctly because the diff3 command was invoked with arguments in an incorrect order. The correct order is the local file first, the base (or "ancestor") second and the other file third. This erroneous behavior had two consequences. First, the output of diff3 would change, since it tries to merge chunks according to maximal matches between the second and first files, and the second and third files. Second, ediff, more precisely, `ediff-do-merge', would consequently try to merge the reverse of the changes from the base to the other file. * lisp/vc/ediff-diff.el (ediff-setup-diff-regions3): In the arguments to `ediff-exec-process', swap the other file with the ancestor (only when merging with an ancestor). (ediff-extract-diffs3): Match the hunk data for the ancestor and the other file correctly. The local variable `three-way-comp' indicates this is a merge with ancestors when it is nil. (Bug#59182)
-rw-r--r--lisp/vc/ediff-diff.el35
1 files changed, 21 insertions, 14 deletions
diff --git a/lisp/vc/ediff-diff.el b/lisp/vc/ediff-diff.el
index 07b853817d1..24647de576d 100644
--- a/lisp/vc/ediff-diff.el
+++ b/lisp/vc/ediff-diff.el
@@ -942,6 +942,9 @@ one optional arguments, diff-number to refine.")
942 (c-prev-pt nil) 942 (c-prev-pt nil)
943 (anc-prev 1) 943 (anc-prev 1)
944 diff-list shift-A shift-B shift-C 944 diff-list shift-A shift-B shift-C
945 (A-idx "1")
946 (B-idx (if three-way-comp "2" "3"))
947 (C-idx (if three-way-comp "3" "2"))
945 ) 948 )
946 949
947 ;; diff list contains word numbers or points, depending on word-mode 950 ;; diff list contains word numbers or points, depending on word-mode
@@ -979,23 +982,23 @@ one optional arguments, diff-number to refine.")
979 (let ((agreement (buffer-substring (match-beginning 1) (match-end 1)))) 982 (let ((agreement (buffer-substring (match-beginning 1) (match-end 1))))
980 ;; if the files A and B are the same and not 3way-comparison, 983 ;; if the files A and B are the same and not 3way-comparison,
981 ;; ignore the difference 984 ;; ignore the difference
982 (if (or three-way-comp (not (string-equal agreement "3"))) 985 (if (or three-way-comp (not (string-equal agreement C-idx)))
983 (let* ((a-begin (car (ediff-get-diff3-group "1"))) 986 (let* ((a-begin (car (ediff-get-diff3-group A-idx)))
984 (a-end (nth 1 (ediff-get-diff3-group "1"))) 987 (a-end (nth 1 (ediff-get-diff3-group A-idx)))
985 (b-begin (car (ediff-get-diff3-group "2"))) 988 (b-begin (car (ediff-get-diff3-group B-idx)))
986 (b-end (nth 1 (ediff-get-diff3-group "2"))) 989 (b-end (nth 1 (ediff-get-diff3-group B-idx)))
987 (c-or-anc-begin (car (ediff-get-diff3-group "3"))) 990 (c-or-anc-begin (car (ediff-get-diff3-group C-idx)))
988 (c-or-anc-end (nth 1 (ediff-get-diff3-group "3"))) 991 (c-or-anc-end (nth 1 (ediff-get-diff3-group C-idx)))
989 (state-of-merge 992 (state-of-merge
990 (cond ((string-equal agreement "1") 'prefer-A) 993 (cond ((string-equal agreement A-idx) 'prefer-A)
991 ((string-equal agreement "2") 'prefer-B) 994 ((string-equal agreement B-idx) 'prefer-B)
992 (t ediff-default-variant))) 995 (t ediff-default-variant)))
993 (state-of-diff-merge 996 (state-of-diff-merge
994 (if (memq state-of-merge '(default-A prefer-A)) 'B 'A)) 997 (if (memq state-of-merge '(default-A prefer-A)) 'B 'A))
995 (state-of-diff-comparison 998 (state-of-diff-comparison
996 (cond ((string-equal agreement "1") 'A) 999 (cond ((string-equal agreement A-idx) 'A)
997 ((string-equal agreement "2") 'B) 1000 ((string-equal agreement B-idx) 'B)
998 ((string-equal agreement "3") 'C))) 1001 ((string-equal agreement C-idx) 'C)))
999 state-of-ancestor 1002 state-of-ancestor
1000 c-begin c-end 1003 c-begin c-end
1001 a-begin-pt a-end-pt 1004 a-begin-pt a-end-pt
@@ -1108,8 +1111,12 @@ one optional arguments, diff-number to refine.")
1108 (get-buffer-create (ediff-unique-buffer-name "*ediff-diff" "*")))) 1111 (get-buffer-create (ediff-unique-buffer-name "*ediff-diff" "*"))))
1109 1112
1110 (message "Computing differences ...") 1113 (message "Computing differences ...")
1111 (ediff-exec-process ediff-diff3-program ediff-diff-buffer 'synchronize 1114 (apply #'ediff-exec-process ediff-diff3-program ediff-diff-buffer 'synchronize
1112 ediff-actual-diff3-options file-A file-B file-C) 1115 ediff-actual-diff3-options
1116 (cons file-A (if ediff-merge-with-ancestor-job
1117 ;; Ancestor must be the middle file
1118 (list file-C file-B)
1119 (list file-B file-C))))
1113 1120
1114 (ediff-prepare-error-list ediff-diff3-ok-lines-regexp ediff-diff-buffer) 1121 (ediff-prepare-error-list ediff-diff3-ok-lines-regexp ediff-diff-buffer)
1115 ;;(message "Computing differences ... done") 1122 ;;(message "Computing differences ... done")