From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Wolfgang Scherer Newsgroups: gmane.emacs.bugs Subject: bug#39452: [PATCH] vc-git-state fails for filenames with wildcards Date: Fri, 7 Feb 2020 23:31:52 +0100 Message-ID: <02dc1f27-64b2-7754-e0c0-5f09922173fa@gmx.de> References: <3a7c412d-4926-9109-8545-31268ce37fca@gmx.de> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------DFBC9CFE6205859F41BECF80" Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="128649"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.9.1 To: Dmitry Gutov , 39452@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Fri Feb 07 23:33:46 2020 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1j0CC2-000XLu-3R for geb-bug-gnu-emacs@m.gmane-mx.org; Fri, 07 Feb 2020 23:33:46 +0100 Original-Received: from localhost ([::1]:35838 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j0CC0-0005cM-Vl for geb-bug-gnu-emacs@m.gmane-mx.org; Fri, 07 Feb 2020 17:33:45 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:53632) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j0CBM-0005c3-Hu for bug-gnu-emacs@gnu.org; Fri, 07 Feb 2020 17:33:06 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j0CBK-0006if-IA for bug-gnu-emacs@gnu.org; Fri, 07 Feb 2020 17:33:04 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:44428) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1j0CBK-0006hU-8g for bug-gnu-emacs@gnu.org; Fri, 07 Feb 2020 17:33:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1j0CBK-0004L1-5o for bug-gnu-emacs@gnu.org; Fri, 07 Feb 2020 17:33:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Wolfgang Scherer Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 07 Feb 2020 22:33:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 39452 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 39452-submit@debbugs.gnu.org id=B39452.158111472216605 (code B ref 39452); Fri, 07 Feb 2020 22:33:02 +0000 Original-Received: (at 39452) by debbugs.gnu.org; 7 Feb 2020 22:32:02 +0000 Original-Received: from localhost ([127.0.0.1]:50401 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1j0CAL-0004JZ-U5 for submit@debbugs.gnu.org; Fri, 07 Feb 2020 17:32:02 -0500 Original-Received: from mout.gmx.net ([212.227.15.15]:56259) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1j0CAJ-0004JD-Cn for 39452@debbugs.gnu.org; Fri, 07 Feb 2020 17:32:00 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1581114712; bh=iBZZKoe90fNqbyMS9WPn1HKqgbUCZBJs2JwMO0Jn90o=; h=X-UI-Sender-Class:Subject:From:To:References:Date:In-Reply-To; b=JxYcBtzGyN2UiWRHRU6YiaaPWF7M8yymeAHuCtyHg4fpKIhQVeygSq/mLBx16tH79 YSl/QCo9EzFhrFBQm8eaqBqb7xOXHcGRXJ1Zoc+ievzkwnQ7XgKsTRJFkjvW9B0pcC tjvrlxyXqBYLPslNnEyjW+le9XjQ337MaCUeyBEk= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Original-Received: from sheckley.simul.de ([87.160.210.52]) by mail.gmx.com (mrgmx004 [212.227.17.190]) with ESMTPSA (Nemesis) id 1MDysg-1iqG0y2s1U-009whq; Fri, 07 Feb 2020 23:31:52 +0100 Original-Received: from [127.0.0.1] (sheckley.simul.de [127.0.0.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by sheckley.simul.de (Postfix) with ESMTPSA id 336D619431CB; Fri, 7 Feb 2020 23:31:52 +0100 (CET) Openpgp: preference=signencrypt Autocrypt: addr=Wolfgang.Scherer@gmx.de; prefer-encrypt=mutual; keydata= xsDiBEb46IgRBACMHOAb1KNo1Ylk+ebri+4R+bG4tyKlqBlrpv8D9/ZwRdXSGt+0DyCHoaAd 7KW7noHapLe87DunABOjKG4nqTGv+dRiWuUBlp3I4aYRFDVa3Da+XnIYkMHKqhK59VEHQCdp Km42nuLS7TS+n99at9YwzTG6VBdOlBKTlRFngOjVLwCg1RGXJ6X3EjS1FKCQeXziURVpWlkD /2zY6Ayhxi62TS84VjikXrrmjXykAAaAmMVEyKKYb9L5pGlqiZz9g/K9xw1EUoZTYuaufquD v4rAGR58K/3V4CYfJLEeshMWiaXHvMmlxMznlG16/um4MvmR8B3r+cx0nOPK1JBdD2qrkNnF Mw8FB+zouLFB4Gt2IUC5IlOmZ8OQA/4qdU53CItzWsCr9Nux4L0qUlRweSmCnV8xGQ2wP5XI MawIQxxREvSrsYDG8cNnYETMg4iQFfIktwAoxCJvuFAwIB6ZxHGF4FcEZm64CXc2u7CmFLqt rVhXhIfMz9oEYC+HhGczGamn9ofbGTFd2hJEtPcQgWNR4f7+aKknmi2+OM0fV29sZmdhbmcg U2NoZXJlciA8d3NAc3ctYW10LndzPsJhBBMRAgAhBQJYmz3YAhsjBQsJCAcCBhUICQoLAgQW AgMBAh4BAheAAAoJEIUCr3Gr112VZZoAoLTBSTp1qGuNhLdXY04iaWCMYmHCAJ4kHPtQ6nTw kEq9qCHgVgXDaY7wjs7ATQRG+OiIEAQAhi0wjcxvA4tychg2NQuwBIf9LX/46l+74+QbewCn a4a+mw/9s5KY In-Reply-To: <3a7c412d-4926-9109-8545-31268ce37fca@gmx.de> Content-Language: de-DE X-Provags-ID: V03:K1:sZQs04zh2z1atFymy3+5I3c/VVFProhnX42E8J3H6BxE1k0tf1+ dO7aL01HaQDTIK0AvLqBN7u7yNuUqbADhtDjvUPzHGqDkCuN+NtY5Ml0/8bqYJGu8ruyGUt Bxh0JrAIQzTscUMQ81A/Yax3fK9J5LsU+mlfZ2efQ0x4rUyZb2/OGI+EGncRPGfHZIkYyjs 4DnkW6bo2MQK+b+v5l8qg== X-UI-Out-Filterresults: notjunk:1;V03:K0:HU7VVmnFstA=:c7RCfOz3uSYQsSzD16zhC0 7mYgOIfsopraKnxRUf6Nv7rJ7F/m8xJPayYBh0kH5OAbTpjRsxghJuRGxXr14Zc6cndnnadI4 2VAYULGZZ1ejOoi09NMzMT89ANslRI+uUuN93F8sQO0VOkjaT3a4PsQCd6XA1lbanGt9Umsbo jrKcGxNWe8sxF8fhx8rqiZ8KIwdJwg4d7Z2UuZwmB33rOrcko9v9ui3dpnCqyf/F1gJZLOkDb 7J4jhspyJVikCbTwmTIUVor82PCh9Fbt4J8TB336/Zs6kJf++eV+/SEbzzavKP+IBEAMsPYJj j4L7TXbZ0iSCBwHB0Hzap8tzFIrNV9BR7QsKM5Sur1eCXrw/WyjmhroQQgBr0KTWoGgTWKjYr GNXbORsurZN98kvERlARH0bqM0y0B8Cw+q+722SyOfei2qd+d4FTIxUdDluG9+rl9U9s9zU0C VXmnmePg3SGxUPRHyBETCL6oKdPwB/Qj7OLTts0h3ZuvneN+mBTkd9PQcun9ar59/KTN7FXIt 07bXP0WiUUrhH3byurTXyLwHSM+Cao/r9TIcTiPf14e1T04FT/ysg5p3bz4t/bVbQmiQmERBS wGxLrNMhhr+Znrk9jzWGJRjxxOCVnSugPBHzBq/bEk8Qpuavnwf7Sx+dIR9atSIN5yXurjWcP JEA7F4z19hNy4ELSY3TRjr6d2wAVq/z4Duc7fFfd292PrtSN3hovxZpUQD0TSiguSOpYz6b/I +Z4LXW8ZawKi9C9jqEpOzq45L8lOUu52jgWgXC9s7pEnISXIs1ZVfsJO0Ro3PUfI9nl6q+Mk X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:175762 Archived-At: This is a multi-part message in MIME format. --------------DFBC9CFE6205859F41BECF80 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Am 07.02.20 um 18:25 schrieb Wolfgang Scherer: > Hi Dmitry, > > Am 07.02.20 um 00:00 schrieb Dmitry Gutov: >> On 06.02.2020 16:59, Wolfgang Scherer wrote: >>> When a filename contains shell wildcard characters matching one or mor= e files, e.g. `test[56].xx` matching both `test5.xx` and `test6.xx`: >>> The command `vc-git-state` does not work correctly. >>> >>> The attched patch fixes this: >>> >>> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (status (apply #'vc-git--r= un-command-string file args))) >>> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (status (apply #'vc-git--r= un-command-string (shell-quote-argument file) args))) >>> >> Thanks for the report and the patch. >> >> I wonder how many other backends commands are broken for files like tha= t: we basically never shell-quote file names. After some research, it seems that adding a pathspec magic to commands tha= t support this feature is the best solution. Here is a patch that applies vc-git--literal-pathspec, vc-git--literal-pat= hspecs to some git commands in vc-git.el. I have tested all augmented comm= ands in the shell and some in emacs. (defun vc-git--literal-pathspec-inner (pathspec) =C2=A0 "Prepend :(literal) path magic to PATHSPEC." =C2=A0 (concat ":(literal)" pathspec)) (defun vc-git--literal-pathspec (pathspec) =C2=A0 "Prepend :(literal) path magic to PATHSPEC." =C2=A0 (and pathspec (vc-git--literal-pathspec-inner pathspec))) (defun vc-git--literal-pathspecs (pathspecs) =C2=A0 "Prepend :(literal) path magic to PATHSPECS." =C2=A0 (mapcar #'vc-git--literal-pathspec-inner pathspecs)) =01 --------------DFBC9CFE6205859F41BECF80 Content-Type: text/x-patch; name="0001-vc-git-state-fails-for-filenames-with-wildcards.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename*0="0001-vc-git-state-fails-for-filenames-with-wildcards.patch" =46rom eab5ef41ff06471d3cf9387d96a09c70e586b0e6 Mon Sep 17 00:00:00 2001 From: Wolfgang Scherer Date: Fri, 7 Feb 2020 23:24:27 +0100 Subject: [PATCH] vc-git-state fails for filenames with wildcards * 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. (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. =2D-- lisp/vc/vc-git.el | 65 ++++++++++++++++++++++++++++++++++----------------= ----- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el index 2caa287..1a38cef 100644 =2D-- a/lisp/vc/vc-git.el +++ b/lisp/vc/vc-git.el @@ -217,6 +217,21 @@ toggle display of the entire list." ;;; BACKEND PROPERTIES +(defun vc-git--literal-pathspec-inner (pathspec) + "Prepend :(literal) path magic to PATHSPEC." + (concat ":(literal)" pathspec)) +;; (vc-git--literal-pathspec-inner "test[56].xx") + +(defun vc-git--literal-pathspec (pathspec) + "Prepend :(literal) path magic to PATHSPEC." + (and pathspec (vc-git--literal-pathspec-inner pathspec))) +;; (vc-git--literal-pathspec nil) +;; (vc-git--literal-pathspec "test[56].xx") + +(defun vc-git--literal-pathspecs (pathspecs) + "Prepend :(literal) path magic to PATHSPECS." + (mapcar #'vc-git--literal-pathspec-inner pathspecs)) + (defun vc-git-revision-granularity () 'repository) (defun vc-git-checkout-model (_files) 'implicit) (defun vc-git-update-on-retrieve-tag () nil) @@ -243,12 +258,12 @@ toggle display of the entire list." (name (file-relative-name file dir)) (str (ignore-errors (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 del= eted ;; file. (when (eq (point-min) (point-max)) (vc-git--out-ok "ls-tree" "--name-only" "-z" "HEA= D" - "--" name)) + "--" (vc-git--literal-pathspec na= me))) (buffer-string)))) (and str (> (length str) (length name)) @@ -330,7 +345,7 @@ in the order given by `git status'." ,@(when (version<=3D "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-path= spec file) args))) (if (null status) ;; If status is nil, there was an error calling git, likely becau= se ;; the file is not in a git repo. @@ -606,28 +621,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-paths= pecs 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)))) @@ -861,12 +876,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 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" "--cach= ed" "--")) (declare-function log-edit-mode "log-edit" ()) (declare-function log-edit-toggle-header "log-edit" (header value)) @@ -933,7 +948,7 @@ It is based on `log-edit-mode', and has Git-specific e= xtensions.") (lambda (value) (when (equal value "yes") (list argument))= ))) ;; When operating on the whole tree, better pass "-a" than ".", sin= ce "." ;; 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 fi= les)) (nconc (if msg-file (list "commit" "-F" (file-local-name msg-file)) (list "commit" "-m")) @@ -960,7 +975,7 @@ It is based on `log-edit-mode', and has Git-specific e= xtensions.") (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=3D fn "") @@ -977,14 +992,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 re= v "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)) @@ -1068,7 +1083,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) @@ -1140,7 +1155,7 @@ If LIMIT is a revision string, use it as an end-revi= sion." (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 @@ -1392,7 +1407,7 @@ This requires git 1.8.4 or later, for the \"-L\" opt= ion 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) @@ -1475,7 +1490,7 @@ This requires git 1.8.4 or later, for the \"-L\" opt= ion 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-gi= t--literal-pathspec fname)) (goto-char (point-max)) (bolp) (zerop (forward-line -1)) @@ -1503,7 +1518,7 @@ This requires git 1.8.4 or later, for the \"-L\" opt= ion 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-pa= thspec file)) (goto-char (point-max)) (bolp) (zerop (forward-line -1)) @@ -1515,7 +1530,7 @@ This requires git 1.8.4 or later, for the \"-L\" opt= ion 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)) @@ -1525,10 +1540,10 @@ This requires git 1.8.4 or later, for the \"-L\" o= ption 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-pathspec 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" "--")) (defvar vc-git-extra-menu-map (let ((map (make-sparse-keymap))) =2D- 2.7.4 --------------DFBC9CFE6205859F41BECF80--