bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

vc-resolve-conflicts is not flexible enough for alternate SCM systems


From: Jonathan Kamens
Subject: vc-resolve-conflicts is not flexible enough for alternate SCM systems
Date: Sat, 5 Jan 2002 22:29:02 -0500

In GNU Emacs 21.1.1 (i386-redhat-linux-gnu, X toolkit, Xaw3d scroll bars)
 of 2001-12-06 on stripples.devel.redhat.com

The supported mechanism for resolving conflicts after merges is not
flexible enough; it has two problems:

1) It can't cope with conflict markers other than those produced by
   rcsmerge or diff3;

2) It can't cope with SCMs that provide ancestor information in their
   conflict markers.

The patch below fixes these problems as follows:

1) Add new backend functions "resolve-select-yours",
   "resolve-select-theirs", and "resolve-select-original".  The first
   selects the workfile changes in the conflicts in in the current
   buffer and returns true on success or nil if there are no
   conflicts.  The second selects the checked-in changes in the
   conflicts in the current buffer.  The third selects the ancestor
   changes in the conflicts in the current buffer and returns true on
   success or nil if there are no ancestor changes (i.e., ediff should
   be called without an ancestor buffer).

2) Add default implementation of these functions which do the same
   thing as the current code.

3) Use these functions in vc-resolve-conflicts for producing the
   buffers used by ediff.  If resolve-select-original returns true,
   then call ediff-merge-buffers-with-ancestor instead of
   editff-merge-buffers, and don't set ediff-default-variant.

4) Always use vc-resolve-conflicts instead of smerge-ediff if a
   backend has a resolve-select-yours function.

Let me know what you think.

Thanks,

  jik

--- /usr/share/emacs/21.1/lisp/vc.el    Mon Sep 24 18:29:15 2001
+++ vc.el       Sat Jan  5 22:19:43 2002
@@ -1925,11 +1925,45 @@
   (if (zerop status) (message "Merge successful")
     (if (fboundp 'smerge-mode) (smerge-mode 1))
     (if (y-or-n-p "Conflicts detected.  Resolve them now? ")
-       (if (fboundp 'smerge-ediff)
+       (if (and (fboundp 'smerge-ediff)
+                (not (vc-find-backend-function (vc-backend file)
+                                               'resolve-select-yours)))
            (smerge-ediff)
          (vc-resolve-conflicts name-A name-B))
       (message "File contains conflict markers"))))
 
+(defun vc-default-resolve-select-yours (backend)
+  (goto-char (point-min))
+  (let ((found nil))
+    (while (re-search-forward (concat "^<<<<<<< "
+                                     (regexp-quote file-name) "\n") nil t)
+      (setq found t)
+      (replace-match "")
+      (if (not (re-search-forward "^=======\n" nil t))
+         (error "Malformed conflict marker"))
+      (replace-match "")
+      (let ((start (point)))
+       (if (not (re-search-forward "^>>>>>>> [0-9.]+\n" nil t))
+           (error "Malformed conflict marker"))
+       (delete-region start (point))))
+    found))
+
+(defun vc-default-resolve-select-theirs (backend)
+  (goto-char (point-min))
+  (while (re-search-forward (concat "^<<<<<<< "
+                                   (regexp-quote file-name) "\n") nil t)
+    (let ((start (match-beginning 0)))
+      (if (not (re-search-forward "^=======\n" nil t))
+         (error "Malformed conflict marker"))
+      (delete-region start (point))
+      (if (not (re-search-forward "^>>>>>>> [0-9.]+\n" nil t))
+         (error "Malformed conflict marker"))
+      (replace-match "")))
+  t)
+
+(defun vc-default-resolve-select-original (backend)
+  nil)
+
 (defvar vc-ediff-windows)
 (defvar vc-ediff-result)
 (eval-when-compile
@@ -1945,53 +1979,52 @@
   (vc-ensure-vc-buffer)
   (let* ((found nil)
          (file-name (file-name-nondirectory buffer-file-name))
+        (backend (vc-backend buffer-file-name))
         (your-buffer   (generate-new-buffer
                          (concat "*" file-name
                                 " " (or name-A "WORKFILE") "*")))
         (other-buffer  (generate-new-buffer
                          (concat "*" file-name
                                 " " (or name-B "CHECKED-IN") "*")))
+         (ancestor-buffer (generate-new-buffer
+                          (concat "*" file-name
+                                  " " (or name-B "ORIGINAL") "*")))
          (result-buffer (current-buffer)))
     (save-excursion
       (set-buffer your-buffer)
       (erase-buffer)
       (insert-buffer result-buffer)
-      (goto-char (point-min))
-      (while (re-search-forward (concat "^<<<<<<< "
-                                       (regexp-quote file-name) "\n") nil t)
-        (setq found t)
-       (replace-match "")
-       (if (not (re-search-forward "^=======\n" nil t))
-           (error "Malformed conflict marker"))
-       (replace-match "")
-       (let ((start (point)))
-         (if (not (re-search-forward "^>>>>>>> [0-9.]+\n" nil t))
-             (error "Malformed conflict marker"))
-         (delete-region start (point))))
-      (if (not found)
+      (if (not (vc-call-backend backend 'resolve-select-yours))
           (progn
             (kill-buffer your-buffer)
             (kill-buffer other-buffer)
+            (kill-buffer ancestor-buffer)
             (error "No conflict markers found")))
+      
       (set-buffer other-buffer)
       (erase-buffer)
       (insert-buffer result-buffer)
+      (vc-call-backend backend 'resolve-select-theirs)
+
+      (set-buffer ancestor-buffer)
+      (erase-buffer)
+      (insert-buffer result-buffer)
       (goto-char (point-min))
-      (while (re-search-forward (concat "^<<<<<<< "
-                                       (regexp-quote file-name) "\n") nil t)
-       (let ((start (match-beginning 0)))
-       (if (not (re-search-forward "^=======\n" nil t))
-           (error "Malformed conflict marker"))
-       (delete-region start (point))
-       (if (not (re-search-forward "^>>>>>>> [0-9.]+\n" nil t))
-           (error "Malformed conflict marker"))
-       (replace-match "")))
-      (let ((config (current-window-configuration))
-            (ediff-default-variant 'default-B))
+      (if (not (vc-call-backend backend 'resolve-select-original))
+          (progn
+            (kill-buffer ancestor-buffer)
+           (setq ancestor-buffer nil)))
+
+      (let ((config (current-window-configuration)))
 
         ;; Fire up ediff.
 
-        (set-buffer (ediff-merge-buffers your-buffer other-buffer))
+        (set-buffer
+        (if ancestor-buffer
+            (ediff-merge-buffers-with-ancestor your-buffer other-buffer
+                                               ancestor-buffer)
+          (let ((ediff-default-variant 'default-B))
+            (ediff-merge-buffers your-buffer other-buffer))))
 
         ;; Ediff is now set up, and we are in the control buffer.
         ;; Do a few further adjustments and take precautions for exit.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]