]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve .gitignore and project-vc-ignores handling
authorDmitry Gutov <dgutov@yandex.ru>
Wed, 2 Dec 2020 02:28:35 +0000 (04:28 +0200)
committerDmitry Gutov <dgutov@yandex.ru>
Wed, 2 Dec 2020 02:28:35 +0000 (04:28 +0200)
* lisp/progmodes/project.el (project-ignores):
Convert .gitignore entries more faithfully.
(project--vc-list-files): Convert "our" ignore entries to
"proper" globs, which is what Git pathspec requires.

lisp/progmodes/project.el

index fd4c256e97d67f59f73decdf98c754deb97a1ea1..449eadc3de73bf1396e7db8626583e4b5460fe3d 100644 (file)
@@ -322,7 +322,7 @@ to find the list of ignores for each directory."
   :group 'project)
 
 (defcustom project-vc-ignores nil
-  "List of patterns to include in `project-ignores'."
+  "List of patterns to add to `project-ignores'."
   :type '(repeat string)
   :safe #'listp)
 
@@ -468,9 +468,26 @@ backend implementation of `project-external-roots'.")
                             (cons "--"
                                   (mapcar
                                    (lambda (i)
-                                     (if (string-match "\\./" i)
-                                         (format ":!/:%s" (substring i 2))
-                                       (format ":!:%s" i)))
+                                     (format
+                                      ":(exclude,glob,top)%s"
+                                      (if (string-match "\\*\\*" i)
+                                          ;; Looks like pathspec glob
+                                          ;; format already.
+                                          i
+                                        (if (string-match "\\./" i)
+                                            ;; ./abc -> abc
+                                            (setq i (substring i 2))
+                                          ;; abc -> **/abc
+                                          (setq i (concat "**/" i))
+                                          ;; FIXME: '**/abc' should also
+                                          ;; match a directory with that
+                                          ;; name, but doesn't (git 2.25.1).
+                                          ;; Maybe we should replace
+                                          ;; such entries with two.
+                                          (if (string-match "/\\'" i)
+                                              ;; abc/ -> abc/**
+                                              (setq i (concat i "**"))))
+                                        i)))
                                    extra-ignores)))))
        (setq files
              (mapcar
@@ -535,12 +552,26 @@ backend implementation of `project-external-roots'.")
     (append
      (when (file-equal-p dir root)
        (setq backend (vc-responsible-backend root))
-       (mapcar
-        (lambda (entry)
-          (if (string-match "\\`/" entry)
-              (replace-match "./" t t entry)
-            entry))
-        (vc-call-backend backend 'ignore-completion-table root)))
+       (delq
+        nil
+        (mapcar
+         (lambda (entry)
+           (cond
+            ((eq ?! (aref entry 0))
+             ;; No support for whitelisting (yet).
+             nil)
+            ((string-match "\\(/\\)[^/]" entry)
+             ;; FIXME: This seems to be Git-specific.
+             ;; And / in the entry (start or even the middle) means
+             ;; the pattern is "rooted".  Or actually it is then
+             ;; relative to its respective .gitignore (of which there
+             ;; could be several), but we only support .gitignore at
+             ;; the root.
+             (if (= (match-beginning 0) 0)
+                 (replace-match "./" t t entry 1)
+               (concat "./" entry)))
+            (t entry)))
+         (vc-call-backend backend 'ignore-completion-table root))))
      (project--value-in-dir 'project-vc-ignores root)
      (mapcar
       (lambda (dir)