emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

emacs-28 e7aa3ece52: Fix vc-git with old Git over Tramp and cygwin-mount


From: Dmitry Gutov
Subject: emacs-28 e7aa3ece52: Fix vc-git with old Git over Tramp and cygwin-mount.el
Date: Tue, 4 Jan 2022 21:10:10 -0500 (EST)

branch: emacs-28
commit e7aa3ece52d26cc7e4d3f3990aff56127389779f
Author: Dmitry Gutov <dgutov@yandex.ru>
Commit: Dmitry Gutov <dgutov@yandex.ru>

    Fix vc-git with old Git over Tramp and cygwin-mount.el
    
    * lisp/vc/vc-git.el (vc-git-use-literal-pathspecs): New variable.
    (vc-git-command, vc-git--call): Use it to determine whether to set
    GIT_LITERAL_PATHSPECS=1 (bug#51497).
    (vc-git--literal-pathspec, vc-git--literal-pathspecs): Remove.
    Update all callers.  This reverts the previous solution for bug#39452.
    
    * lisp/progmodes/project.el (project--vc-list-files):
    Use the new variable.
---
 etc/NEWS                  |  7 +++++
 lisp/progmodes/project.el |  2 ++
 lisp/vc/vc-git.el         | 74 ++++++++++++++++++++++-------------------------
 3 files changed, 44 insertions(+), 39 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index f007c00b89..1e882883b5 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1949,6 +1949,13 @@ String or list of strings specifying switches for Git 
log under VC.
 If you are still using it with any regularity, please file a bug
 report with some details.
 
+---
+*** New variable 'vc-git-use-literal-pathspecs'.
+The Git backend's function now treat all file names "literally", where
+some of them previously could interpret file names (pathspecs) as
+globs when they contain appropriate characters.  Functions can bind
+the aforementioned variable to nil locally to avoid this.
+
 ** Gnus
 
 +++
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index bd2ca421ae..1000e8c87f 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -494,10 +494,12 @@ backend implementation of `project-external-roots'.")
 (declare-function vc-hg-command "vc-hg")
 
 (defun project--vc-list-files (dir backend extra-ignores)
+  (defvar vc-git-use-literal-pathspecs)
   (pcase backend
     (`Git
      (let ((default-directory (expand-file-name (file-name-as-directory dir)))
            (args '("-z"))
+           (vc-git-use-literal-pathspecs nil)
            files)
        ;; Include unregistered.
        (setq args (append args '("-c" "-o" "--exclude-standard")))
diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el
index 3519f08646..7072b8e483 100644
--- a/lisp/vc/vc-git.el
+++ b/lisp/vc/vc-git.el
@@ -223,6 +223,12 @@ included in the completions."
 ;; History of Git commands.
 (defvar vc-git-history nil)
 
+;; Default to t because commands which don't support literal pathspecs
+;; ignore the environment variable silently.
+(defvar vc-git-use-literal-pathspecs t
+  "Non-nil to treat pathspecs in commands literally.
+Good example of file name that needs this: \"test[56].xx\".")
+
 ;; Clear up the cache to force vc-call to check again and discover
 ;; new functions when we reload this file.
 (put 'Git 'vc-functions nil)
@@ -242,20 +248,6 @@ included in the completions."
 ;;;###autoload         (load "vc-git" nil t)
 ;;;###autoload         (vc-git-registered file))))
 
-;; Good example of file name that needs this: "test[56].xx".
-(defun vc-git--literal-pathspec (file)
-  "Prepend :(literal) path magic to FILE."
-  (when file
-    ;; Expand abbreviated file names.
-    (when (file-name-absolute-p file)
-      (setq file (expand-file-name file)))
-    (concat ":(literal)" (file-local-name file))))
-
-(defun vc-git--literal-pathspecs (files)
-  "Prepend :(literal) path magic to FILES."
-  (unless (vc-git--file-list-is-rootdir files)
-    (mapcar #'vc-git--literal-pathspec files)))
-
 (defun vc-git-registered (file)
   "Check whether FILE is registered with git."
   (let ((dir (vc-git-root file)))
@@ -269,12 +261,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" "--" 
(vc-git--literal-pathspec name))
+                      (vc-git--out-ok "ls-files" "-c" "-z" "--" 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"
-                                        "--" (vc-git--literal-pathspec name)))
+                                        "--" name))
                       (buffer-string))))
           (and str
                (> (length str) (length name))
@@ -356,7 +348,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 (vc-git--literal-pathspec 
file) args)))
+        (status (apply #'vc-git--run-command-string 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.
@@ -634,28 +626,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 (vc-git--literal-pathspecs 
files) "add" "--refresh" "--")
+           (vc-git-command (current-buffer) 'async files "add" "--refresh" 
"--")
          (vc-git-command (current-buffer) 'async nil
                          "update-index" "--refresh")))
       ('ls-files-added
-       (vc-git-command (current-buffer) 'async (vc-git--literal-pathspecs 
files)
+       (vc-git-command (current-buffer) 'async files
                        "ls-files" "-z" "-c" "-s" "--"))
       ('ls-files-up-to-date
-       (vc-git-command (current-buffer) 'async (vc-git--literal-pathspecs 
files)
+       (vc-git-command (current-buffer) 'async files
                        "ls-files" "-z" "-c" "-s" "--"))
       ('ls-files-conflict
-       (vc-git-command (current-buffer) 'async (vc-git--literal-pathspecs 
files)
+       (vc-git-command (current-buffer) 'async files
                        "ls-files" "-z" "-u" "--"))
       ('ls-files-unknown
-       (vc-git-command (current-buffer) 'async (vc-git--literal-pathspecs 
files)
+       (vc-git-command (current-buffer) 'async files
                        "ls-files" "-z" "-o" "--exclude-standard" "--"))
       ('ls-files-ignored
-       (vc-git-command (current-buffer) 'async (vc-git--literal-pathspecs 
files)
+       (vc-git-command (current-buffer) 'async 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 (vc-git--literal-pathspecs 
files)
+       (vc-git-command (current-buffer) 'async files
                        "diff-index" "--relative" "-z" "-M" "HEAD" "--")))
     (vc-run-delayed
       (vc-git-after-dir-status-stage git-state))))
@@ -883,12 +875,12 @@ The car of the list is the current branch."
     (when flist
       (vc-git-command nil 0 flist "update-index" "--add" "--"))
     (when dlist
-      (vc-git-command nil 0 (vc-git--literal-pathspecs dlist) "add"))))
+      (vc-git-command nil 0 dlist "add"))))
 
 (defalias 'vc-git-responsible-p #'vc-git-root)
 
 (defun vc-git-unregister (file)
-  (vc-git-command nil 0 (vc-git--literal-pathspec file) "rm" "-f" "--cached" 
"--"))
+  (vc-git-command nil 0 file "rm" "-f" "--cached" "--"))
 
 (declare-function log-edit-mode "log-edit" ())
 (declare-function log-edit-toggle-header "log-edit" (header value))
@@ -954,7 +946,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 (vc-git--literal-pathspecs files))
+      (apply #'vc-git-command nil 0 (if only files)
              (nconc (if msg-file (list "commit" "-F"
                                        (file-local-name msg-file))
                       (list "commit" "-m"))
@@ -981,7 +973,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
-                    (vc-git--literal-pathspec file) "ls-files" "-z" 
"--full-name" "--")))
+                    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 "")
@@ -998,14 +990,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 (vc-git--literal-pathspec file) "checkout" (or rev 
"HEAD")))
+  (vc-git-command nil 0 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 (vc-git--literal-pathspec file) "reset" "-q" "--")
-    (vc-git-command nil nil (vc-git--literal-pathspec file) "checkout" "-q" 
"--")))
+    (vc-git-command nil 0 file "reset" "-q" "--")
+    (vc-git-command nil nil file "checkout" "-q" "--")))
 
 (defvar vc-git-error-regexp-alist
   '(("^ \\(.+\\)\\> *|" 1 nil nil 0))
@@ -1089,7 +1081,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 (vc-git--literal-pathspec directory) 
"status" "--porcelain" "--"))
+          (vc-git--run-command-string directory "status" "--porcelain" "--"))
          (lines (when status (split-string status "\n" 'omit-nulls)))
          files)
     (dolist (line lines files)
@@ -1178,7 +1170,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 (vc-git--literal-pathspecs files)
+              'async files
               (append
                '("log" "--no-color")
                 (when (and vc-git-print-log-follow
@@ -1432,7 +1424,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
-              (vc-git--literal-pathspecs files)
+               files
                command
                "--exit-code"
                (append (vc-switches 'git 'diff)
@@ -1517,7 +1509,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 "--" 
(vc-git--literal-pathspec fname))
+                          (vc-git--out-ok "rev-list" "-2" rev "--" fname)
                           (goto-char (point-max))
                           (bolp)
                           (zerop (forward-line -1))
@@ -1545,7 +1537,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 "--" 
(vc-git--literal-pathspec file))
+             (vc-git--out-ok "rev-list" "-1" rev "--" file)
              (goto-char (point-max))
              (bolp)
              (zerop (forward-line -1))
@@ -1557,7 +1549,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" "--" 
(vc-git--literal-pathspec file))
+                  (vc-git--out-ok "rev-list" "HEAD" "--" file)
                   (goto-char (point-min))
                   (search-forward current-rev nil t)
                   (zerop (forward-line -1))
@@ -1567,13 +1559,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 (vc-git--literal-pathspec file) "rm" "-f" "--"))
+  (vc-git-command nil 0 file "rm" "-f" "--"))
 
 (defun vc-git-rename-file (old new)
   (vc-git-command nil 0 (list old new) "mv" "-f" "--"))
 
 (defun vc-git-mark-resolved (files)
-  (vc-git-command nil 0 (vc-git--literal-pathspecs files) "add"))
+  (vc-git-command nil 0 files "add"))
 
 (defvar vc-git-extra-menu-map
   (let ((map (make-sparse-keymap)))
@@ -1796,6 +1788,8 @@ The difference to vc-do-command is that this function 
always invokes
         (process-environment
          (append
           `("GIT_DIR"
+            ,@(when vc-git-use-literal-pathspecs
+                '("GIT_LITERAL_PATHSPECS=1"))
             ;; Avoid repository locking during background operations
             ;; (bug#21559).
             ,@(when revert-buffer-in-progress-p
@@ -1833,6 +1827,8 @@ The difference to vc-do-command is that this function 
always invokes
        (process-environment
         (append
          `("GIT_DIR"
+            ,@(when vc-git-use-literal-pathspecs
+                '("GIT_LITERAL_PATHSPECS=1"))
            ;; Avoid repository locking during background operations
            ;; (bug#21559).
            ,@(when revert-buffer-in-progress-p



reply via email to

[Prev in Thread] Current Thread [Next in Thread]