(dired-do-print): Put spaces between lpr switches.
[bpt/emacs.git] / lisp / vc.el
index 5bbd061..ec712ee 100644 (file)
@@ -131,6 +131,9 @@ and that its contents match what the master file says.")
 (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)
 
@@ -215,7 +218,12 @@ the master name of FILE; this is appended to an optional list of FLAGS."
     (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)
@@ -492,8 +500,12 @@ lock steals will raise an error.
 (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))
@@ -561,7 +573,7 @@ level to check it in under.  COMMENT, if specified, is the checkin comment."
   (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."
@@ -576,29 +588,36 @@ level to check it in under.  COMMENT, if specified, is the checkin comment."
 
 (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.
@@ -1175,6 +1194,7 @@ A prefix argument means do not revert the buffer afterwards."
        (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: ")
@@ -1521,10 +1541,36 @@ Return nil if there is no such person."
   (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.
@@ -1535,7 +1581,10 @@ Return nil if there is no such person."
               (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