Function: vc-only-files-state-and-model

vc-only-files-state-and-model is a byte-compiled function defined in vc.el.gz.

Signature

(vc-only-files-state-and-model FILES BACKEND)

Documentation

Compute last three vc-deduce-fileset return value elements for FILES.

FILES should be a pair, or list of pairs, of files and their VC states. BACKEND is the VC backend responsible for FILES.

Source Code

;; Defined in /usr/src/emacs/lisp/vc/vc.el.gz
(defun vc-only-files-state-and-model (files backend)
  "Compute last three `vc-deduce-fileset' return value elements for FILES.
FILES should be a pair, or list of pairs, of files and their VC states.
BACKEND is the VC backend responsible for FILES."
  (let* ((files (if (proper-list-p files) files (list files)))
         files* states-alist states state)
    ;; Check that all files are in a consistent state, since we use that
    ;; state to decide which operation to perform.
    (pcase-dolist (`(,file . ,state) files)
      (push file files*)
      (push file (alist-get state states-alist nil nil #'eq)))
    (setq states (mapcar #'car states-alist))
    (cond ((length= states 1)
           (setq state (car states)))
          ((cl-subsetp states '(added missing removed edited))
           (setq state 'edited))

          ;; Special, but common case: checking in both changes and new
          ;; files at once.  The actual registration is delayed until
          ;; `vc-checkin' so that if the user changes their mind while
          ;; entering the log message, we leave things as we found them.
          ;;
          ;; An alternative would be to delay it until the backend
          ;; `vc-*-checkin'.  The advantages would be that those
          ;; functions could complete the whole operation in fewer total
          ;; shell commands, and if the checkin itself fails they could
          ;; ensure the file is left unregistered then too (e.g. for Git
          ;; we may be able to use 'git add -N', though that would still
          ;; require a subsequent 'git reset').
          ;; The disadvantage would be a more complex VC API because we
          ;; would have to distinguish between backends which can and
          ;; can't handle registration and checkin together.
          ((and (cl-subsetp states
                            '(added missing removed edited unregistered))
                (y-or-n-p "\
Some files are unregistered; register them before checking in?"))
           (setq state 'edited))

          (t
           (let* ((pred (lambda (elt)
                          (memq (car elt) '(added missing removed edited))))
                  (compat-alist (cl-remove-if-not pred states-alist))
                  (other-alist (cl-remove-if pred states-alist))
                  (first (car (or compat-alist other-alist)))
                  (second (if compat-alist
                              (car other-alist)
                            (cadr other-alist))))
             (error "\
To apply VC operations to multiple files, the files must be in similar VC states.
%s in state %s clashes with %s in state %s"
                    (cadr first) (car first) (cadr second) (car second)))))
    (list files* state
          (and state (not (eq state 'unregistered))
               (vc-checkout-model backend files*)))))