[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.
- vc-resolve-conflicts is not flexible enough for alternate SCM systems,
Jonathan Kamens <=