Function: vc-git-project-list-files

vc-git-project-list-files is a byte-compiled function defined in project.el.gz.

Signature

(vc-git-project-list-files DIR EXTRA-IGNORES)

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/project.el.gz
(defun vc-git-project-list-files (dir extra-ignores)
  (defvar vc-git-use-literal-pathspecs)
  (if (not (or (not extra-ignores)
               (version<= "2.13" (vc-git--program-version))))
      ;; Need newer Git to use negative pathspec like we do".
      (vc-default-project-list-files 'Git dir extra-ignores)
    (let* ((default-directory (expand-file-name (file-name-as-directory dir)))
           (vc-git-use-literal-pathspecs nil)
           (include-untracked (project--value-in-dir
                               'project-vc-include-untracked
                               dir
                               nil))
           (submodules (project--git-submodules))
           (gitver (vc-git--program-version))
           (dedup (and (version<= "2.31" gitver) '("--deduplicate")))
           (args (append '("-z" "-c" "--exclude-standard")
                         (and (<= 31 emacs-major-version)
                              (version<= "2.35" gitver)
                              '("--sparse"))
                         (and include-untracked '("-o"))
                         dedup))
           files)
      (when extra-ignores
        (setq args (append args
                           (cons "--"
                                 (mapcar
                                  (lambda (i)
                                    (format
                                     ":(exclude,glob,top)%s"
                                     (if (string-match-p "\\*\\*" i)
                                         ;; Looks like pathspec glob
                                         ;; format already.
                                         i
                                       (if (string-prefix-p "./" i)
                                           ;; ./abc -> abc
                                           (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-suffix-p "/" i)
                                             ;; abc/ -> abc/**
                                             (concat i "**")
                                           i)))))
                                  extra-ignores)))))
      (setq files
            (delq nil
                  (mapcar
                   (lambda (file)
                     (unless (or (member file submodules)
                                 ;; Should occur for sparse directories
                                 ;; only, when sparse index is enabled.
                                 (directory-name-p file))
                       (if project-files-relative-names
                           file
                         (concat default-directory file))))
                   (split-string
                    (with-output-to-string
                      (apply #'vc-git-command standard-output 0 nil "ls-files" args))
                    "\0" t))))
      (when (project--vc-merge-submodules-p default-directory nil)
        ;; Unfortunately, 'ls-files --recurse-submodules' conflicts with '-o'.
        (let ((sub-files
               (mapcar
                (lambda (module)
                  (when (file-directory-p module)
                    (let ((sub-files
                           (vc-git-project-list-files
                            (concat default-directory module)
                            extra-ignores)))
                      (if project-files-relative-names
                          (mapcar (lambda (file)
                                    (concat (file-name-as-directory module) file))
                                  sub-files)
                        sub-files))))
                submodules)))
          (setq files
                (apply #'nconc files sub-files))))
      ;; 'git ls-files' returns duplicate entries for merge conflicts.
      (if dedup files (delete-consecutive-dups files)))))