]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix vc-git-state for filenames with wildcards
authorWolfgang Scherer <wolfgang.scherer@gmx.de>
Sun, 15 Aug 2021 01:02:23 +0000 (04:02 +0300)
committerDmitry Gutov <dgutov@yandex.ru>
Sun, 15 Aug 2021 01:22:26 +0000 (04:22 +0300)
* lisp/vc/vc-git.el: (vc-git--literal-pathspec-inner),
(vc-git--literal-pathspec), (vc-git--literal-pathspecs) new functions
to add ":(literal)" pathspec magic (bug#39452).

(vc-git-registered), (vc-git-state), (vc-git-dir-status-goto-stage),
(vc-git-register), (vc-git-unregister), (vc-git-checkin),
(vc-git-find-revision), (vc-git-checkout), (vc-git-revert),
(vc-git-conflicted-files), (vc-git-print-log), (vc-git-diff),
(vc-git-previous-revision), (vc-git-next-revision),
(vc-git-delete-file), (vc-git-rename-file) functions
vc-git--literal-pathspec, vc-git--literal-pathspecs applied.

lisp/vc/vc-git.el

index 5828a83debcf0babb0b35e774f5b9edc5c2029ef..ffe1e6832cef8a0ae745953bb625126d78f6573e 100644 (file)
@@ -242,6 +242,15 @@ included in the completions."
 ;;;###autoload         (load "vc-git" nil t)
 ;;;###autoload         (vc-git-registered file))))
 
+(defun vc-git--literal-pathspec (pathspec)
+  "Prepend :(literal) path magic to PATHSPEC."
+  ;; Good example of PATHSPEC that needs this: "test[56].xx".
+  (and pathspec (concat ":(literal)" pathspec)))
+
+(defun vc-git--literal-pathspecs (pathspecs)
+  "Prepend :(literal) path magic to PATHSPECS."
+  (mapcar #'vc-git--literal-pathspec pathspecs))
+
 (defun vc-git-registered (file)
   "Check whether FILE is registered with git."
   (let ((dir (vc-git-root file)))
@@ -255,12 +264,12 @@ included in the completions."
                (name (file-relative-name file dir))
                (str (with-demoted-errors "Error: %S"
                       (cd dir)
-                      (vc-git--out-ok "ls-files" "-c" "-z" "--" name)
+                      (vc-git--out-ok "ls-files" "-c" "-z" "--" (vc-git--literal-pathspec name))
                       ;; If result is empty, use ls-tree to check for deleted
                       ;; file.
                       (when (eq (point-min) (point-max))
                         (vc-git--out-ok "ls-tree" "--name-only" "-z" "HEAD"
-                                        "--" name))
+                                        "--" (vc-git--literal-pathspec name)))
                       (buffer-string))))
           (and str
                (> (length str) (length name))
@@ -342,7 +351,7 @@ in the order given by `git status'."
             ,@(when (version<= "1.7.6.3" (vc-git--program-version))
                 '("--ignored"))
             "--"))
-        (status (apply #'vc-git--run-command-string file args)))
+        (status (apply #'vc-git--run-command-string (vc-git--literal-pathspec file) args)))
     (if (null status)
         ;; If status is nil, there was an error calling git, likely because
         ;; the file is not in a git repo.
@@ -620,28 +629,28 @@ or an empty string if none."
     (pcase (vc-git-dir-status-state->stage git-state)
       ('update-index
        (if files
-           (vc-git-command (current-buffer) 'async files "add" "--refresh" "--")
+           (vc-git-command (current-buffer) 'async (vc-git--literal-pathspecs files) "add" "--refresh" "--")
          (vc-git-command (current-buffer) 'async nil
                          "update-index" "--refresh")))
       ('ls-files-added
-       (vc-git-command (current-buffer) 'async files
+       (vc-git-command (current-buffer) 'async (vc-git--literal-pathspecs files)
                        "ls-files" "-z" "-c" "-s" "--"))
       ('ls-files-up-to-date
-       (vc-git-command (current-buffer) 'async files
+       (vc-git-command (current-buffer) 'async (vc-git--literal-pathspecs files)
                        "ls-files" "-z" "-c" "-s" "--"))
       ('ls-files-conflict
-       (vc-git-command (current-buffer) 'async files
+       (vc-git-command (current-buffer) 'async (vc-git--literal-pathspecs files)
                        "ls-files" "-z" "-u" "--"))
       ('ls-files-unknown
-       (vc-git-command (current-buffer) 'async files
+       (vc-git-command (current-buffer) 'async (vc-git--literal-pathspecs files)
                        "ls-files" "-z" "-o" "--exclude-standard" "--"))
       ('ls-files-ignored
-       (vc-git-command (current-buffer) 'async files
+       (vc-git-command (current-buffer) 'async (vc-git--literal-pathspecs files)
                        "ls-files" "-z" "-o" "-i" "--directory"
                        "--no-empty-directory" "--exclude-standard" "--"))
       ;; --relative added in Git 1.5.5.
       ('diff-index
-       (vc-git-command (current-buffer) 'async files
+       (vc-git-command (current-buffer) 'async (vc-git--literal-pathspecs files)
                        "diff-index" "--relative" "-z" "-M" "HEAD" "--")))
     (vc-run-delayed
       (vc-git-after-dir-status-stage git-state))))
@@ -867,14 +876,14 @@ The car of the list is the current branch."
          (push crt dlist)
        (push crt flist)))
     (when flist
-      (vc-git-command nil 0 flist "update-index" "--add" "--"))
+      (vc-git-command nil 0 (vc-git--literal-pathspecs flist) "update-index" "--add" "--"))
     (when dlist
-      (vc-git-command nil 0 dlist "add"))))
+      (vc-git-command nil 0 (vc-git--literal-pathspecs dlist) "add"))))
 
 (defalias 'vc-git-responsible-p #'vc-git-root)
 
 (defun vc-git-unregister (file)
-  (vc-git-command nil 0 file "rm" "-f" "--cached" "--"))
+  (vc-git-command nil 0 (vc-git--literal-pathspec file) "rm" "-f" "--cached" "--"))
 
 (declare-function log-edit-mode "log-edit" ())
 (declare-function log-edit-toggle-header "log-edit" (header value))
@@ -941,7 +950,7 @@ It is based on `log-edit-mode', and has Git-specific extensions.")
                (lambda (value) (when (equal value "yes") (list argument)))))
       ;; When operating on the whole tree, better pass "-a" than ".", since "."
       ;; fails when we're committing a merge.
-      (apply #'vc-git-command nil 0 (if only files)
+      (apply #'vc-git-command nil 0 (if only (vc-git--literal-pathspecs files))
              (nconc (if msg-file (list "commit" "-F"
                                        (file-local-name msg-file))
                       (list "commit" "-m"))
@@ -968,7 +977,7 @@ It is based on `log-edit-mode', and has Git-specific extensions.")
         (coding-system-for-write 'binary)
         (fullname
          (let ((fn (vc-git--run-command-string
-                    file "ls-files" "-z" "--full-name" "--")))
+                    (vc-git--literal-pathspec file) "ls-files" "-z" "--full-name" "--")))
            ;; ls-files does not return anything when looking for a
            ;; revision of a file that has been renamed or removed.
            (if (string= fn "")
@@ -985,14 +994,14 @@ It is based on `log-edit-mode', and has Git-specific extensions.")
                    (vc-git-root file)))
 
 (defun vc-git-checkout (file &optional rev)
-  (vc-git-command nil 0 file "checkout" (or rev "HEAD")))
+  (vc-git-command nil 0 (vc-git--literal-pathspec file) "checkout" (or rev "HEAD")))
 
 (defun vc-git-revert (file &optional contents-done)
   "Revert FILE to the version stored in the git repository."
   (if contents-done
       (vc-git-command nil 0 file "update-index" "--")
-    (vc-git-command nil 0 file "reset" "-q" "--")
-    (vc-git-command nil nil file "checkout" "-q" "--")))
+    (vc-git-command nil 0 (vc-git--literal-pathspec file) "reset" "-q" "--")
+    (vc-git-command nil nil (vc-git--literal-pathspec file) "checkout" "-q" "--")))
 
 (defvar vc-git-error-regexp-alist
   '(("^ \\(.+\\)\\> *|" 1 nil nil 0))
@@ -1076,7 +1085,7 @@ This prompts for a branch to merge from."
 (defun vc-git-conflicted-files (directory)
   "Return the list of files with conflicts in DIRECTORY."
   (let* ((status
-          (vc-git--run-command-string directory "status" "--porcelain" "--"))
+          (vc-git--run-command-string (vc-git--literal-pathspec directory) "status" "--porcelain" "--"))
          (lines (when status (split-string status "\n" 'omit-nulls)))
          files)
     (dolist (line lines files)
@@ -1157,7 +1166,7 @@ If LIMIT is a revision string, use it as an end-revision."
     (let ((inhibit-read-only t))
       (with-current-buffer buffer
        (apply #'vc-git-command buffer
-              'async files
+              'async (vc-git--literal-pathspecs files)
               (append
                '("log" "--no-color")
                 (when (and vc-git-print-log-follow
@@ -1408,7 +1417,7 @@ This requires git 1.8.4 or later, for the \"-L\" option of \"git log\"."
     (if vc-git-diff-switches
         (apply #'vc-git-command (or buffer "*vc-diff*")
               1 ; bug#21969
-              files
+              (vc-git--literal-pathspecs files)
                command
                "--exit-code"
                (append (vc-switches 'git 'diff)
@@ -1493,7 +1502,7 @@ This requires git 1.8.4 or later, for the \"-L\" option of \"git log\"."
       (let* ((fname (file-relative-name file))
              (prev-rev (with-temp-buffer
                          (and
-                          (vc-git--out-ok "rev-list" "-2" rev "--" fname)
+                          (vc-git--out-ok "rev-list" "-2" rev "--" (vc-git--literal-pathspec fname))
                           (goto-char (point-max))
                           (bolp)
                           (zerop (forward-line -1))
@@ -1521,7 +1530,7 @@ This requires git 1.8.4 or later, for the \"-L\" option of \"git log\"."
          (current-rev
           (with-temp-buffer
             (and
-             (vc-git--out-ok "rev-list" "-1" rev "--" file)
+             (vc-git--out-ok "rev-list" "-1" rev "--" (vc-git--literal-pathspec file))
              (goto-char (point-max))
              (bolp)
              (zerop (forward-line -1))
@@ -1533,7 +1542,7 @@ This requires git 1.8.4 or later, for the \"-L\" option of \"git log\"."
           (and current-rev
                (with-temp-buffer
                  (and
-                  (vc-git--out-ok "rev-list" "HEAD" "--" file)
+                  (vc-git--out-ok "rev-list" "HEAD" "--" (vc-git--literal-pathspec file))
                   (goto-char (point-min))
                   (search-forward current-rev nil t)
                   (zerop (forward-line -1))
@@ -1543,13 +1552,13 @@ This requires git 1.8.4 or later, for the \"-L\" option of \"git log\"."
     (or (vc-git-symbolic-commit next-rev) next-rev)))
 
 (defun vc-git-delete-file (file)
-  (vc-git-command nil 0 file "rm" "-f" "--"))
+  (vc-git-command nil 0 (vc-git--literal-pathspecs file) "rm" "-f" "--"))
 
 (defun vc-git-rename-file (old new)
-  (vc-git-command nil 0 (list old new) "mv" "-f" "--"))
+  (vc-git-command nil 0 (vc-git--literal-pathspecs (list old new)) "mv" "-f" "--"))
 
 (defun vc-git-mark-resolved (files)
-  (vc-git-command nil 0 files "add"))
+  (vc-git-command nil 0 (vc-git--literal-pathspecs files) "add"))
 
 (defvar vc-git-extra-menu-map
   (let ((map (make-sparse-keymap)))