          (log (if match
                   (substring comment (match-end 0))
                   "")))
-    (vc-darcs-do-command 'record 'async nil
-                         "-a" "--pipe" (file-name-nondirectory file))
+    (vc-darcs-do-command 'record 'async nil "-a" "--pipe" file)
     (with-current-buffer (get-buffer "*vc*")
       (process-send-string nil
                            (format "%s\n%s\n%s\n%s"
                                    date vc-darcs-mail-address patch-name log))
       (process-send-eof))))
 
-(defun vc-darcs-checkout (file &optional editable rev destfile)
-  "This gets revision REV of FILE from the darcs repository.
+(defun vc-darcs-find-version (file rev buffer)
+  "This gets revision REV of FILE from the darcs repository."
+  (let ((rev (vc-darcs-rev-to-hash rev file)))
+    (apply #'vc-do-command buffer 0 vc-darcs-program-name file
+           "show" "contents"
+           (and rev (list "--match" (concat "hash " rev))))))
+
+(defun vc-darcs-checkout (file &optional editable rev)
+  "Check out FILE from the Darcs repository.
 EDITABLE is ignored."
-  (let ((rev (vc-darcs-rev-to-hash rev file t))
-        (destfile (or destfile file)))
-    (cond
-      ((or (not rev) (equal rev (vc-darcs-workfile-version file)))
-       (copy-file (vc-darcs-pristine-file file) destfile t))
-      (t
-       ;; darcs does not currently allow getting an old version of a
-       ;; file.  We kludge around this by getting the pristine version and
-       ;; reverting the right patch.
-       (let ((temp (make-temp-file "vc-darcs")))
-         (copy-file (vc-darcs-pristine-file file) temp t)
-         (with-temp-buffer
-           (vc-do-command t nil vc-darcs-program-name
-                          (file-name-nondirectory file)
-                          "diff" "-u" 
-                          "--from-match" (concat "hash " rev)
-                          "--to-match" 
-                          (concat "hash " (vc-darcs-workfile-version file)))
-           (shell-command-on-region 1 (point-max)
-                                    (concat "patch -R " temp)
-                                    t))
-         (rename-file temp (or destfile file) t))))))
+  (let ((rev (vc-darcs-rev-to-hash rev file)))
+    (when (and rev (not (equal rev (vc-darcs-workfile-version file))))
+      (error "Cannot checkout old revisions with darcs."))
+    (or (file-exists-p file)
+        (vc-darcs-do-command "revert" 0 file "-a"))))
+
+(defun vc-darcs-revert (file &optional contents-done)
+  "Revert FILE back to the current workfile version."
+  (vc-darcs-do-command "revert" 0 file "-a"))
 
 (defun vc-darcs-print-log (file)
   "Print the logfile for the current darcs repository to the *vc* buffer."
   (vc-darcs-do-command 'changes 'async (and (not vc-darcs-full-log) file)))
 
-(defun vc-darcs-diff (file &optional rev1 rev2)
+(defun vc-darcs-diff (file &optional rev1 rev2 buffer)
   "Show the differences in FILE between revisions REV1 and REV2."
-  (let* ((rev1 (vc-darcs-rev-to-hash rev1 file t))
+  (let* ((async (not vc-disable-async-diff))
+         (rev1 (vc-darcs-rev-to-hash rev1 file t))
          (rev2 (vc-darcs-rev-to-hash rev2 file))
          (arguments (cdr (assq 'diff vc-darcs-program-arguments)))
          (from (and rev1 (list "--from-match" (concat "hash " rev1))))
          (to (and rev2 (list "--to-match" (concat "hash " rev2)))))
-    (apply #'vc-do-command "*vc-diff*" 'async
-           vc-darcs-program-name (file-name-nondirectory file)
-           "diff"
-           (append from to arguments))))
+    (let ((status (apply #'vc-do-command (or buffer "*vc-diff*")
+                         (if async 'async 1)
+                         vc-darcs-program-name file
+                         "diff"
+                         (append from to arguments))))
+      (if async 1 status))))
 
 (defun vc-darcs-rename-file (old new)
   "Rename the file OLD to NEW in the darcs repository."
-  (call-process vc-darcs-program-name nil nil nil "mv" old new))
+  (vc-darcs-do-command 'mv 0 nil (expand-file-name old) (expand-file-name new)))
+
+(defun vc-darcs-delete-file (file)
+  (delete-file (expand-file-name file)))
+
+(defun vc-darcs-parse-integer (string)
+  (let* ((c (read-from-string string))
+         (n (car c)))
+    (if (integerp n) n 0)))
 
 (defun vc-darcs-annotate-command (file buffer &optional rev)
+  "Produce an annotated display of fiLE in BUFFER.
+For Darcs, hashes and times are stored in text properties."
   (let* ((rev (vc-darcs-rev-to-hash rev file))
          (data
           (with-temp-buffer
-            (apply #'vc-do-command t nil vc-darcs-program-name
-                   (file-name-nondirectory file)
+            (apply #'vc-do-command t 0 vc-darcs-program-name file
                    "annotate" "--xml"
                    (and rev (list "--match" (concat "hash " rev))))
             (let ((output (xml-parse-region 1 (point-max))))


(defun vc-darcs-rev-to-hash (rev file &optional off-by-one)
  (cond
    ((null rev) nil)
    ((not off-by-one)
     (cond
       ((vc-darcs-hash-p rev) rev)

       (let ((changes (apply #'vc-darcs-changes file flags)))
         (and (cdr changes) (car (last changes 2))))))))

(defun vc-darcs-next-version (file rev)
  (vc-darcs-rev-to-hash rev file t))

(defun vc-darcs-previous-version (file rev)
  (let ((flags
         (if (vc-darcs-hash-p rev)
             (list "--to-match" (concat "hash " rev))
             (list "--to-patch" rev))))
    (let ((changes (apply #'vc-darcs-changes file flags)))
      (cadr changes))))

(defun vc-darcs-registered (file)
  "Return non-nil if FILE is handled by darcs."
  (let* ((file (expand-file-name file))
         ;; Vc-dired is recursive by default, and will call this function
         ;; for all the files under _darcs.  Get rid of those early.
         (special (vc-darcs-special-file-p file))
         (root (and (not special) (vc-darcs-find-root file))))
    (and root
         (let ((default-directory root))
           (with-temp-buffer
             (vc-do-command (current-buffer) nil vc-darcs-program-name
                            nil "show" "files")
             (goto-char (point-min))
             (catch 'found
               (while (looking-at "[^\n]+")
                 (when (equal (expand-file-name (match-string 0)) file)
                   (throw 'found t))
                 (forward-line))
               nil))))))

(defun vc-darcs-file-times-equal-p (file1 file2)
  (equal (nth 5 (file-attributes file1)) (nth 5 (file-attributes file2))))

(defun vc-darcs-state (file)
  "Return the state of FILE."
  (with-temp-buffer
    (vc-do-command t nil vc-darcs-program-name file
                   "whatsnew" "--summary")
    (goto-char (point-max))
    (previous-line 1)
    (if (looking-at "^No changes!")
        'up-to-date
        'edited)))

(defun vc-darcs-checkout-model (file)
  "Indicate how FILE is checked out.  This is always IMPLICIT with darcs."
  'implicit)

(defun vc-darcs-responsible-p (file)
  "Return non-nil if we feel responsible for FILE,
which can also be a directory."
  (vc-darcs-registered file))

(defun vc-darcs-could-register (file)
  "Return non-nil if FILE could be registered."
  (let ((file (expand-file-name file)))
    (and (not (vc-darcs-special-file-p file))
         (vc-darcs-find-root file)
         t)))

(defun vc-darcs-workfile-version (file)
  "Return the current working-dir version of FILE.
