diff options
Diffstat (limited to 'lisp/vc/vc.el')
-rw-r--r-- | lisp/vc/vc.el | 65 |
1 files changed, 49 insertions, 16 deletions
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index 4cbd2658f80..8def7da3776 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -979,12 +979,22 @@ be reported. If NO-ERROR is nil, signal an error that no VC backend is responsible for the given file." (or (and (not (file-directory-p file)) (vc-backend file)) - (catch 'found - ;; First try: find a responsible backend. If this is for registration, - ;; it must be a backend under which FILE is not yet registered. - (dolist (backend vc-handled-backends) - (and (vc-call-backend backend 'responsible-p file) - (throw 'found backend)))) + ;; First try: find a responsible backend. If this is for registration, + ;; it must be a backend under which FILE is not yet registered. + (let ((dirs (delq nil + (mapcar + (lambda (backend) + (when-let ((dir (vc-call-backend + backend 'responsible-p file))) + (cons backend dir))) + vc-handled-backends)))) + ;; Just a single response (or none); use it. + (if (< (length dirs) 2) + (caar dirs) + ;; Several roots; we seem to have one vc inside another's + ;; directory. Choose the most specific. + (caar (sort dirs (lambda (d1 d2) + (< (length (cdr d2)) (length (cdr d1)))))))) (unless no-error (error "No VC backend is responsible for %s" file)))) @@ -1038,7 +1048,9 @@ If the current buffer is in `vc-dir' or Dired mode, FILESET is the list of marked files, or the current directory if no files are marked. Otherwise, if the current buffer is visiting a version-controlled -file, FILESET is a single-file list containing that file's name. +file or is an indirect buffer whose base buffer visits a +version-controlled file, FILESET is a single-file list containing +that file's name. Otherwise, if ALLOW-UNREGISTERED is non-nil and the visited file is unregistered, FILESET is a single-file list containing the name of the visited file. @@ -1052,6 +1064,14 @@ possible values of STATE are explained in `vc-state', and MODEL in the returned list. BEWARE: this function may change the current buffer." + (with-current-buffer (or (buffer-base-buffer) (current-buffer)) + (vc-deduce-fileset-1 not-state-changing + allow-unregistered + state-model-only-files))) + +(defun vc-deduce-fileset-1 (not-state-changing + allow-unregistered + state-model-only-files) (let (backend) (cond ((derived-mode-p 'vc-dir-mode) @@ -1073,7 +1093,7 @@ BEWARE: this function may change the current buffer." (derived-mode-p 'dired-mode))))) (progn ;FIXME: Why not `with-current-buffer'? --Stef. (set-buffer vc-parent-buffer) - (vc-deduce-fileset not-state-changing allow-unregistered state-model-only-files))) + (vc-deduce-fileset-1 not-state-changing allow-unregistered state-model-only-files))) ((and (not buffer-file-name) (setq backend (vc-responsible-backend default-directory))) (list backend nil)) @@ -1883,6 +1903,10 @@ state of each file in the fileset." t (list backend (list rootdir)) rev1 rev2 (called-interactively-p 'interactive))))) +(defun vc-maybe-buffer-sync (not-urgent) + (with-current-buffer (or (buffer-base-buffer) (current-buffer)) + (when buffer-file-name (vc-buffer-sync not-urgent)))) + ;;;###autoload (defun vc-diff (&optional historic not-urgent) "Display diffs between file revisions. @@ -1895,9 +1919,17 @@ saving the buffer." (interactive (list current-prefix-arg t)) (if historic (call-interactively 'vc-version-diff) - (when buffer-file-name (vc-buffer-sync not-urgent)) - (vc-diff-internal t (vc-deduce-fileset t) nil nil - (called-interactively-p 'interactive)))) + (vc-maybe-buffer-sync not-urgent) + (let ((fileset (vc-deduce-fileset t))) + (vc-buffer-sync-fileset fileset not-urgent) + (vc-diff-internal t fileset nil nil + (called-interactively-p 'interactive))))) + +(defun vc-buffer-sync-fileset (fileset not-urgent) + (dolist (filename (cadr fileset)) + (when-let ((buffer (find-buffer-visiting filename))) + (with-current-buffer buffer + (vc-buffer-sync not-urgent))))) ;;;###autoload (defun vc-diff-mergebase (_files rev1 rev2) @@ -1974,7 +2006,7 @@ saving the buffer." (interactive (list current-prefix-arg t)) (if historic (call-interactively 'vc-version-ediff) - (when buffer-file-name (vc-buffer-sync not-urgent)) + (vc-maybe-buffer-sync not-urgent) (vc-version-ediff (cadr (vc-deduce-fileset t)) nil nil))) ;;;###autoload @@ -1991,7 +2023,7 @@ saving the buffer." (if historic ;; We want the diff for the VC root dir. (call-interactively 'vc-root-version-diff) - (when buffer-file-name (vc-buffer-sync not-urgent)) + (vc-maybe-buffer-sync not-urgent) (let ((backend (vc-deduce-backend)) (default-directory default-directory) rootdir working-revision) @@ -2031,16 +2063,17 @@ Return nil if the root directory cannot be identified." If the current file is named `F', the revision is named `F.~REV~'. If `F.~REV~' already exists, use it instead of checking it out again." (interactive - (save-current-buffer + (with-current-buffer (or (buffer-base-buffer) (current-buffer)) (vc-ensure-vc-buffer) (list (vc-read-revision "Revision to visit (default is working revision): " (list buffer-file-name))))) + (set-buffer (or (buffer-base-buffer) (current-buffer))) (vc-ensure-vc-buffer) (let* ((file buffer-file-name) (revision (if (string-equal rev "") - (vc-working-revision file) - rev))) + (vc-working-revision file) + rev))) (switch-to-buffer-other-window (vc-find-revision file revision)))) (defun vc-find-revision (file revision &optional backend) |