all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Dmitry Gutov <dgutov@yandex.ru>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 51497@debbugs.gnu.org, andrewjmoreton@gmail.com
Subject: bug#51497: 29.0.50; (vc-print-log) broken over TRAMP
Date: Mon, 27 Dec 2021 03:36:33 +0200	[thread overview]
Message-ID: <90ac6d38-e448-2415-60c3-aacd10f73172@yandex.ru> (raw)
In-Reply-To: <838rxy7bq3.fsf@gnu.org>

[-- Attachment #1: Type: text/plain, Size: 886 bytes --]

On 08.11.2021 21:18, Eli Zaretskii wrote:
> So what would you suggest as the way forward, for both emacs-28 and
> the master branches (the 2 solutions could be different)?  Do you
> still prefer to go with your original patch for emacs-28?

I'm still of two minds a little bit: conceptually, the current approach 
is a little cleaner because it forces the opt-in approach, and thus 
won't affect any command (or use of functions like 
vc-git--run-command-string outside of vc-git.el) that didn't opt into 
using literal pathspecs.

But my original approach is simpler and shorter, and together with an 
opt-out var seems to solve every problem so far. It doesn't need version 
detection either (a patch to have it work on remote hosts was discussed 
previously here).

So here's the patch (my current preferred solution for both emacs-28 and 
master).

Waiting for feedback from AndyM.

[-- Attachment #2: redo-literal-pathspecs.diff --]
[-- Type: text/x-patch, Size: 11333 bytes --]

diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index 3b634471ac..4c4eb915ed 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -502,10 +502,12 @@ project-files
 (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 5c6a39aec9..19264c9d3c 100644
--- a/lisp/vc/vc-git.el
+++ b/lisp/vc/vc-git.el
@@ -223,6 +223,12 @@ vc-git-revision-complete-only-branches
 ;; 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 @@ vc-git-update-on-retrieve-tag
 ;;;###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 @@ vc-git-registered
                (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))
@@ -358,7 +350,7 @@ vc-git-state
             ,@(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.
@@ -636,28 +628,28 @@ vc-git-dir-status-goto-stage
     (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))))
@@ -885,12 +877,12 @@ vc-git-register
     (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))
@@ -956,7 +948,7 @@ vc-git-checkin
                (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"))
@@ -983,7 +975,7 @@ vc-git-find-revision
 	 (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 "")
@@ -1000,14 +992,14 @@ vc-git-find-ignore-file
 		    (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))
@@ -1091,7 +1083,7 @@ vc-git-merge-branch
 (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)
@@ -1180,7 +1172,7 @@ vc-git-print-log
     (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
@@ -1434,7 +1426,7 @@ vc-git-diff
     (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)
@@ -1519,7 +1511,7 @@ vc-git-previous-revision
       (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))
@@ -1547,7 +1539,7 @@ vc-git-next-revision
          (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))
@@ -1559,7 +1551,7 @@ vc-git-next-revision
           (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))
@@ -1569,13 +1561,13 @@ vc-git-next-revision
     (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)))
@@ -1797,6 +1789,8 @@ vc-git-command
         (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
@@ -1834,6 +1828,8 @@ vc-git--call
 	(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

  parent reply	other threads:[~2021-12-27  1:36 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-30  1:24 bug#51497: 29.0.50; (vc-print-log) broken over TRAMP dima
2021-10-30 12:48 ` Lars Ingebrigtsen
2021-10-30 13:21   ` Dmitry Gutov
2021-10-30 19:01   ` Dima Kogan
2021-10-31  0:56     ` Dmitry Gutov
2021-10-31  6:58       ` Dima Kogan
2021-10-31  8:16         ` Michael Albinus
2021-10-31 12:26           ` Dmitry Gutov
2021-10-31 16:05             ` Michael Albinus
2021-11-03  2:00               ` Dmitry Gutov
2021-11-03 17:09                 ` Michael Albinus
2021-11-05  2:00                   ` Dmitry Gutov
2021-11-03  2:03         ` Dmitry Gutov
2021-11-03  3:03           ` Dima Kogan
2021-11-03 12:06             ` Dmitry Gutov
2021-11-06 13:22               ` Dmitry Gutov
2021-11-06 15:51                 ` Eli Zaretskii
2021-11-06 19:44                   ` Dmitry Gutov
2021-11-06 19:52                     ` Eli Zaretskii
2021-11-06 22:11                       ` Andy Moreton
2021-11-06 22:21                         ` Dmitry Gutov
2021-11-06 23:03                           ` Andy Moreton
2021-11-07  0:11                             ` Dmitry Gutov
2021-11-07  6:47                               ` Eli Zaretskii
2021-11-07 10:43                                 ` Andy Moreton
2021-11-07 22:36                                 ` Dmitry Gutov
2021-11-08 12:49                                   ` Eli Zaretskii
2021-11-08 17:30                                     ` Dmitry Gutov
2021-11-08 18:18                                       ` Eli Zaretskii
2021-12-23 10:28                                         ` Lars Ingebrigtsen
2021-12-26  0:53                                           ` Dmitry Gutov
2021-12-27  1:36                                         ` Dmitry Gutov [this message]
2022-01-03  3:59                                           ` Dmitry Gutov
2022-01-03 21:15                                             ` Dima Kogan
2022-01-03 22:51                                               ` Dmitry Gutov
2022-01-04  3:28                                                 ` Eli Zaretskii
2022-01-05  2:09                                                   ` Dmitry Gutov
2022-01-21 13:50                                                     ` Lars Ingebrigtsen
2022-01-21 14:11                                                       ` Dmitry Gutov
2022-01-03 21:16                                             ` Andy Moreton
2021-11-07  6:43                             ` Eli Zaretskii
2021-11-07 10:45                               ` Andy Moreton
2021-11-07  6:31                         ` Eli Zaretskii
2021-11-06 22:19                       ` Dmitry Gutov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=90ac6d38-e448-2415-60c3-aacd10f73172@yandex.ru \
    --to=dgutov@yandex.ru \
    --cc=51497@debbugs.gnu.org \
    --cc=andrewjmoreton@gmail.com \
    --cc=eliz@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.