(defvar vc-log-operation nil)
(defvar vc-log-after-operation-hook nil)
(defvar vc-checkout-writable-buffer-hook 'vc-checkout-writable-buffer)
+;; In a log entry buffer, this is a local variable
+;; that points to the buffer for which it was made
+;; (either a file, or a VC dired buffer).
(defvar vc-parent-buffer nil)
(defvar vc-parent-buffer-name nil)
(if vc-file
(setq squeezed (append squeezed (list vc-file))))
(let ((default-directory (file-name-directory (or file "./")))
- (exec-path (if vc-path (append exec-path vc-path) exec-path)))
+ (exec-path (if vc-path (append exec-path vc-path) exec-path))
+ ;; Add vc-path to PATH for the execution of this command.
+ (process-environment
+ (cons (concat "PATH=" (getenv "PATH")
+ ":" (mapconcat 'identity vc-path ":"))
+ process-environment)))
(setq status (apply 'call-process command nil t nil squeezed)))
(goto-char (point-max))
(forward-line -1)
(defun vc-register (&optional override comment)
"Register the current file into your version-control system."
(interactive "P")
- (if (vc-name buffer-file-name)
- (error "This file is already registered"))
+ (let ((master (vc-name buffer-file-name)))
+ (and master (file-exists-p master)
+ (error "This file is already registered"))
+ (and master
+ (not (y-or-n-p "Previous master file has vanished. Make a new one? "))
+ (error "This file is already registered")))
;; Watch out for new buffers of size 0: the corresponding file
;; does not exist yet, even though buffer-modified-p is nil.
(if (and (not (buffer-modified-p))
(vc-start-entry file rev
(or comment (not vc-initial-comment))
"Enter initial comment." 'vc-backend-admin
- 'vc-checkout-writable-buffer-hook))
+ nil))
(defun vc-checkout (file &optional writable)
"Retrieve a copy of the latest version of the given file."
(defun vc-steal-lock (file rev &optional owner)
"Steal the lock on the current workfile."
- (interactive)
- (if (not owner)
- (setq owner (vc-locking-user file)))
- (if (not (y-or-n-p (format "Take the lock on %s:%s from %s? " file rev owner)))
- (error "Steal cancelled"))
- (pop-to-buffer (get-buffer-create "*VC-mail*"))
- (setq default-directory (expand-file-name "~/"))
- (auto-save-mode auto-save-default)
- (mail-mode)
- (erase-buffer)
- (mail-setup owner (format "%s:%s" file rev) nil nil nil
- (list (list 'vc-finish-steal file rev)))
- (goto-char (point-max))
- (insert
- (format "I stole the lock on %s:%s, " file rev)
- (current-time-string)
- ".\n")
- (message "Please explain why you stole the lock. Type C-c C-c when done."))
+ (let (file-description)
+ (if (not owner)
+ (setq owner (vc-locking-user file)))
+ (if rev
+ (setq file-description (format "%s:%s" file rev))
+ (setq file-description file))
+ (if (not (y-or-n-p (format "Take the lock on %s from %s? "
+ file-description owner)))
+ (error "Steal cancelled"))
+ (pop-to-buffer (get-buffer-create "*VC-mail*"))
+ (setq default-directory (expand-file-name "~/"))
+ (auto-save-mode auto-save-default)
+ (mail-mode)
+ (erase-buffer)
+ (mail-setup owner (format "Stolen lock on %s" file-description) nil nil nil
+ (list (list 'vc-finish-steal file rev)))
+ (goto-char (point-max))
+ (insert
+ (format "I stole the lock on %s, " file-description)
+ (current-time-string)
+ ".\n")
+ (message "Please explain why you stole the lock. Type C-c C-c when done.")))
;; This is called when the notification has been sent.
(defun vc-finish-steal (file version)
(vc-backend-steal file version)
- (vc-resynch-window file t t))
+ (if (get-file-buffer file)
+ (save-excursion
+ (set-buffer (get-file-buffer file))
+ (vc-resynch-window file t t))))
(defun vc-checkin (file &optional rev comment)
"Check in the file specified by FILE.
(vc-checkout (buffer-file-name) nil)))
))
+;;;###autoload
(defun vc-rename-file (old new)
"Rename file OLD to NEW, and rename its master file likewise."
(interactive "fVC rename file: \nFRename to: ")
(let ((filename (or workfile file)))
(message "Checking out %s..." filename)
(vc-backend-dispatch file
- (vc-do-command 0 "get" file ;; SCCS
- (if writable "-e")
- (if workfile (concat "-G" workfile))
- (and rev (concat "-r" (vc-lookup-triple file rev))))
+ (if workfile ;; SCCS
+ ;; Some SCCS implementations allow checking out directly to a
+ ;; file using the -G option, but then some don't so use the
+ ;; least common denominator approach and use the -p option
+ ;; ala RCS.
+ (let ((vc-modes (logior (file-modes (vc-name file))
+ (if writable 128 0)))
+ (failed t))
+ (unwind-protect
+ (progn
+ (vc-do-command
+ 0 "/bin/sh" file "-c"
+ ;; Some shells make the "" dummy argument into $0
+ ;; while others use the shell's name as $0 and
+ ;; use the "" as $1. The if-statement
+ ;; converts the latter case to the former.
+ (format "if [ x\"$1\" = x ]; then shift; fi; \
+ umask %o; exec >\"$1\" || exit; \
+ shift; umask %o; exec get \"$@\""
+ (logand 511 (lognot vc-modes))
+ (logand 511 (lognot (default-file-modes))))
+ "" ; dummy argument for shell's $0
+ filename
+ (if writable "-e")
+ "-p" (and rev (concat "-r" (vc-lookup-triple file rev))))
+ (setq failed nil))
+ (and failed (file-exists-p filename) (delete-file filename))))
+ (vc-do-command 0 "get" file ;; SCCS
+ (if writable "-e")
+ (and rev (concat "-r" (vc-lookup-triple file rev)))))
(if workfile ;; RCS
;; RCS doesn't let us check out into arbitrary file names directly.
;; Use `co -p' and make stdout point to the correct file.
(progn
(vc-do-command
0 "/bin/sh" file "-c"
- (format "umask %o; exec >\"$1\" || exit; shift; umask %o; exec co \"$@\""
+ ;; See the SCCS case, above, regarding the if-statement.
+ (format "if [ x\"$1\" = x ]; then shift; fi; \
+ umask %o; exec >\"$1\" || exit; \
+ shift; umask %o; exec co \"$@\""
(logand 511 (lognot vc-modes))
(logand 511 (lognot (default-file-modes))))
"" ; dummy argument for shell's $0