]> git.eshelyaron.com Git - emacs.git/commitdiff
(vc-merge, vc-backend-merge): New functions.
authorAndré Spiegel <spiegel@gnu.org>
Sun, 5 Apr 1998 18:45:06 +0000 (18:45 +0000)
committerAndré Spiegel <spiegel@gnu.org>
Sun, 5 Apr 1998 18:45:06 +0000 (18:45 +0000)
(vc-resolve-conflicts): Added optional parameters for buffer names.
(vc-branch-p): New function.

lisp/vc.el

index 503e4f6e29091453cdc94c9a6639b5f587ae4ce8..4751b0de090f35326e2c9e41abfa95eaaf18ffa1 100644 (file)
@@ -5,7 +5,7 @@
 ;; Author:     Eric S. Raymond <esr@snark.thyrsus.com>
 ;; Maintainer: Andre Spiegel <spiegel@inf.fu-berlin.de>
 
-;; $Id: vc.el,v 1.216 1998/04/04 05:22:37 rms Exp spiegel $
+;; $Id: vc.el,v 1.217 1998/04/05 18:43:15 spiegel Exp spiegel $
 
 ;; This file is part of GNU Emacs.
 
@@ -388,6 +388,10 @@ If nil, VC itself computes this value when it is first needed."
   ;; return t if REV is a revision on the trunk
   (not (eq nil (string-match "\\`[0-9]+\\.[0-9]+\\'" rev))))
 
+(defun vc-branch-p (rev)
+  ;; return t if REV is a branch revision
+  (not (eq nil (string-match "\\`[0-9]+\\(\\.[0-9]+\\.[0-9]+\\)*\\'" rev))))
+
 (defun vc-branch-part (rev)
   ;; return the branch part of a revision number REV
   (substring rev 0 (string-match "\\.[0-9]+\\'" rev)))
@@ -1457,7 +1461,51 @@ the variable `vc-header-alist'."
     (vc-restore-buffer-context context)))
 
 ;;;###autoload
-(defun vc-resolve-conflicts ()
+(defun vc-merge ()
+  (interactive)
+  (vc-ensure-vc-buffer)
+  (vc-buffer-sync)
+  (let* ((file buffer-file-name)
+        (backend (vc-backend file))
+        first-version second-version locking-user)
+    (if (eq backend 'SCCS)
+       (error "Sorry, merging is not implemented for SCCS")
+      (setq locking-user (vc-locking-user file))
+      (if (eq (vc-checkout-model file) 'manual)
+         (if (not locking-user)
+             (if (not (y-or-n-p 
+                       (format "File must be %s for merging.  %s now? "
+                               (if (eq backend 'RCS) "locked" "writable")
+                               (if (eq backend 'RCS) "Lock" "Check out"))))
+                 (error "Merge aborted")
+               (vc-checkout file t))
+           (if (not (string= locking-user (vc-user-login-name)))
+               (error "File is locked by %s" locking-user))))
+      (setq first-version (read-string "Branch or version to merge from: "))
+      (if (and (>= (elt first-version 0) ?0)
+              (<= (elt first-version 0) ?9))
+         (if (not (vc-branch-p first-version))
+             (setq second-version 
+                   (read-string "Second version: " 
+                                (concat (vc-branch-part first-version) ".")))
+           ;; We want to merge an entire branch.  Set versions
+           ;; accordingly, so that vc-backend-merge understands us.
+           (setq second-version first-version)
+           ;; first-version must be the starting point of the branch
+           (setq first-version (vc-branch-part first-version))))
+      (let ((status (vc-backend-merge file first-version second-version)))
+       (if (and (eq (vc-checkout-model file) 'implicit)
+                (not (vc-locking-user file)))
+           (vc-file-setprop file 'vc-locking-user nil))
+       (vc-resynch-buffer file t t)
+       (if (not (zerop status))
+           (if (y-or-n-p "Conflicts detected.  Resolve them now? ")
+               (vc-resolve-conflicts "WORKFILE" "MERGE SOURCE")
+             (message "File contains conflict markers"))
+         (message "Merge successful"))))))
+
+;;;###autoload
+(defun vc-resolve-conflicts (&optional name-A name-B)
   "Invoke ediff to resolve conflicts in the current buffer.
 The conflicts must be marked with rcsmerge conflict markers."
   (interactive)
@@ -1465,9 +1513,11 @@ The conflicts must be marked with rcsmerge conflict markers."
   (let* ((found nil)
          (file-name (file-name-nondirectory buffer-file-name))
         (your-buffer   (generate-new-buffer 
-                         (concat "*" file-name " WORKFILE*")))
+                         (concat "*" file-name 
+                                " " (or name-A "WORKFILE") "*")))
         (other-buffer  (generate-new-buffer 
-                         (concat "*" file-name " CHECKED-IN*")))
+                         (concat "*" file-name 
+                                " " (or name-B "CHECKED-IN") "*")))
          (result-buffer (current-buffer)))
     (save-excursion 
       (set-buffer your-buffer)
@@ -2802,6 +2852,32 @@ THRESHOLD, nil otherwise"
            (error "Couldn't analyze cvs update result"))))
     (message "Merging changes into %s...done" file)))
 
+(defun vc-backend-merge (file first-version &optional second-version)
+  ;; Merge the changes between FIRST-VERSION and SECOND-VERSION into
+  ;; the current working copy of FILE.  It is assumed that FILE is
+  ;; locked and writable (vc-merge ensures this).
+  (vc-backend-dispatch file
+   ;; SCCS
+   (error "Sorry, merging is not implemented for SCCS")
+   ;; RCS
+   (vc-do-command nil 1 "rcsmerge" file 'MASTER
+                 "-kk" ;; ignore keyword conflicts
+                 (concat "-r" first-version)
+                 (if second-version (concat "-r" second-version)))
+   ;; CVS
+   (progn
+     (vc-do-command nil 0 "cvs" file 'WORKFILE
+                   "update" "-kk"
+                   (concat "-j" first-version)
+                   (concat "-j" second-version))
+     (save-excursion
+       (set-buffer (get-buffer "*vc*"))
+       (goto-char (point-min))
+       (if (re-search-forward "conflicts during merge" nil t)
+          1  ;; signal error
+        0  ;; signal success
+        )))))
+
 (defun vc-check-headers ()
   "Check if the current file has any headers in it."
   (interactive)