Commit 1d502d5a authored by André Spiegel's avatar André Spiegel

(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.

(vc-next-action-on-file): Call vc-transfer-file at appropriate places.
(vc-switch-backend): New function.
(vc-prefix-map): Bind `vc-switch-backend' to `b'.
(vc-register): Fix prompt.
(vc-unregister, vc-default-unregister): New functions.
(vc-version-diff): Handle empty buffer in sentinel.
parent 0db2c43c
......@@ -73,8 +73,7 @@
;;;;;;;;;;;;;;;;; Backend-specific functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; for each operation FUN, the backend should provide a function vc-BACKEND-FUN.
;; Operations marked with a `-' instead of a `*' have a sensible default
;; behavior.
;; Operations marked with a `-' instead of a `*' are optional.
;; * registered (file)
;; * state (file)
......@@ -91,6 +90,8 @@
;; - steal-lock (file &optional version)
;; Only required if files can be locked by somebody else.
;; * register (file rev comment)
;; * unregister (file backend)
;; - receive-file (file move)
;; - responsible-p (file)
;; Should also work if FILE is a directory (ends with a slash).
;; - could-register (file)
......@@ -135,6 +136,7 @@
;; * print-log (file)
;; Insert the revision log of FILE into the current buffer.
;; - show-log-entry (version)
;; - comment-history (file)
;; - update-changelog (files)
;; Find changelog entries for FILES, or for all files at or below
;; the default-directory if FILES is nil.
......@@ -372,6 +374,7 @@ and that its contents match what the master file says."
(defvar vc-prefix-map
(let ((map (make-sparse-keymap)))
(define-key map "a" 'vc-update-change-log)
(define-key map "b" 'vc-switch-backend)
(define-key map "c" 'vc-cancel-version)
(define-key map "d" 'vc-directory)
(define-key map "g" 'vc-annotate)
......@@ -833,6 +836,7 @@ If VERBOSE is non-nil, query the user rather than using default parameters."
(if (not (vc-registered file))
(vc-register verbose comment)
(vc-recompute-state file)
(vc-mode-line file)
(setq state (vc-state file))
;; up-to-date
......@@ -841,8 +845,13 @@ If VERBOSE is non-nil, query the user rather than using default parameters."
;; go to a different version
(setq version (read-string "Branch or version to move to: "))
(vc-checkout file (eq (vc-checkout-model file) 'implicit) version))
(setq version
(read-string "Branch, version, or backend to move to: "))
(let ((vsym (intern (upcase version))))
(if (member vsym vc-handled-backends)
(vc-transfer-file file vsym)
(vc-checkout file (eq (vc-checkout-model file) 'implicit)
((not (eq (vc-checkout-model file) 'implicit))
;; check the file out
(vc-checkout file t))
......@@ -876,8 +885,13 @@ If VERBOSE is non-nil, query the user rather than using default parameters."
(if (yes-or-no-p "Revert to master version? ")
(t ;; normal action
(if verbose (setq version (read-string "New version: ")))
(vc-checkin file version comment))))
(if (not verbose)
(vc-checkin file nil comment)
(setq version (read-string "New version or backend: "))
(let ((vsym (intern (upcase version))))
(if (member vsym vc-handled-backends)
(vc-transfer-file file vsym)
(vc-checkin file version comment)))))))
;; locked by somebody else
((stringp state)
......@@ -1044,8 +1058,8 @@ first backend that could register the file is used."
(vc-start-entry buffer-file-name
(if set-version
(read-string "Initial version level for %s: "
(read-string (format "Initial version level for %s: "
;; TODO: Use backend-specific init version.
(or comment (not vc-initial-comment))
......@@ -1093,6 +1107,15 @@ The default is to return nil always."
The default implementation returns t for all files."
(defun vc-unregister (file backend)
"Unregister FILE from version control system BACKEND."
(vc-call-backend backend 'unregister file)
(vc-file-clearprops file))
(defun vc-default-unregister (backend file)
"Default implementation of vc-unregister, signals an error."
(error "Unregistering files is not supported for %s" backend))
(defun vc-resynch-window (file &optional keep noquery)
"If FILE is in the current buffer, either revert or unvisit it.
The choice between revert (to see expanded keywords) and unvisit depends on
......@@ -1488,7 +1511,9 @@ files in or below it."
;; Gnus-5.8.5 sets up an autoload for diff-mode, even if it's
;; not available. Work around that.
(if (require 'diff-mode nil t) (diff-mode))
(vc-exec-after '(progn (goto-char (point-min))
(vc-exec-after '(progn (if (eq (buffer-size) 0)
(insert "No differences found.\n"))
(goto-char (point-min))
......@@ -2155,6 +2180,79 @@ A prefix argument NOREVERT means do not revert the buffer afterwards."
(vc-resynch-buffer file t t)))
(message "Version %s has been removed from the master" target))))
(defun vc-switch-backend (file backend)
"Make BACKEND the current version control system for FILE.
FILE must already be registered in BACKEND. The change is not
permanent, only for the current session. This function only changes
VC's perspective on FILE, it does not register or unregister it."
(intern (upcase (read-string "Switch to backend: ")))))
(vc-file-clearprops file)
(vc-file-setprop file 'vc-backend backend)
(vc-resynch-buffer file t t))
(defun vc-index-of (backend)
"Return the index of BACKEND in vc-handled-backends."
(- (length vc-handled-backends)
(length (memq backend vc-handled-backends))))
(defun vc-transfer-file (file new-backend)
"Transfer FILE to another version control system NEW-BACKEND.
If NEW-BACKEND has a higher precedence than FILE's current backend
\(i.e. it comes earlier in vc-handled-backends), then register FILE in
NEW-BACKEND, using the version number from the current backend as the
base level. If NEW-BACKEND has a lower precedence than the current
backend, then commit all changes that were made under the current
backend to NEW-BACKEND, and unregister FILE from the current backend.
\(If FILE is not yet registered under NEW-BACKEND, register it.)"
(let ((old-backend (vc-backend file)))
(if (eq old-backend new-backend)
(error "%s is the current backend of %s"
new-backend file)
(vc-call-backend new-backend 'receive-file file
(< (vc-index-of old-backend)
(vc-index-of new-backend)))
`((vc-backend ,new-backend))))
(vc-resynch-buffer file t t)))
(defun vc-default-receive-file (backend file move)
"Let BACKEND receive FILE from another version control system.
If MOVE is non-nil, then FILE is unregistered from the old
backend and its comment history is used as the initial contents
of the log entry buffer."
(let ((old-backend (vc-backend file))
(rev (vc-workfile-version file))
(state (vc-state file))
(comment (and move
(vc-find-backend-function old-backend 'comment-history)
(vc-call 'comment-history file))))
(if move (vc-unregister file old-backend))
(vc-file-clearprops file)
(if (not (vc-call-backend backend 'registered file))
;; TODO: If the file was 'edited under the old backend,
;; this should actually register the version
;; it was based on.
(vc-call-backend backend 'register file rev "")
`((vc-backend ,backend)))
(vc-file-setprop file 'vc-backend backend)
(vc-file-setprop file 'vc-state 'edited)
(set-file-modes file
(logior (file-modes file) 128)))
(when (or move (eq state 'edited))
(vc-file-setprop file 'vc-state 'edited)
;; TODO: The comment history should actually become the
;; initial contents of the log entry buffer.
(and comment (ring-insert vc-comment-ring comment))
(vc-checkin file))))
(defun vc-rename-master (oldmaster newfile templates)
"Rename OLDMASTER to be the master file for NEWFILE based on TEMPLATES."
(let* ((dir (file-name-directory (expand-file-name oldmaster)))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment