From 0273f261a71089e5fea3cbfc45a654e508e49497 Mon Sep 17 00:00:00 2001 From: Wolfgang Scherer Date: Fri, 21 Feb 2020 21:28:11 +0100 Subject: [PATCH] Don't write absolute filenames and duplicate strings to CVS ignore files * lisp/vc/vc-cvs.el (vc-cvs-ignore): Expand filename correctly and pass on only the basename as the pattern. (vc-cvs-append-to-ignore) Do not write duplicate strings to .cvsignore. New optional parameter SORT to more explicitly control sorting of the ignore entries. (Bug#37215) * lisp/vc/pcvs.el (cvs-mode-ignore): Call 'vc-cvs-append-to-ignore' with SORT argument. --- lisp/vc/pcvs.el | 4 ++-- lisp/vc/vc-cvs.el | 45 ++++++++++++++++++++++++++++++++------------- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/lisp/vc/pcvs.el b/lisp/vc/pcvs.el index dcba504401c..cb0494ee91c 100644 --- a/lisp/vc/pcvs.el +++ b/lisp/vc/pcvs.el @@ -106,7 +106,6 @@ ;; right now, it's killed without further ado. ;; - make `cvs-mode-ignore' allow manually entering a pattern. ;; to which dir should it apply ? -;; - cvs-mode-ignore should try to remove duplicate entries. ;; - maybe poll/check CVS/Entries files to react to external `cvs' commands ? ;; - some kind of `cvs annotate' support ? ;; but vc-annotate can be used instead. @@ -1972,7 +1971,8 @@ This command ignores files that are not flagged as `Unknown'." (interactive) (dolist (fi (cvs-mode-marked 'ignore)) (vc-cvs-append-to-ignore (cvs-fileinfo->dir fi) (cvs-fileinfo->file fi) - (eq (cvs-fileinfo->subtype fi) 'NEW-DIR)) + (eq (cvs-fileinfo->subtype fi) 'NEW-DIR) + cvs-sort-ignore-file) (setf (cvs-fileinfo->type fi) 'DEAD)) (cvs-cleanup-collection cvs-cookies nil nil nil)) diff --git a/lisp/vc/vc-cvs.el b/lisp/vc/vc-cvs.el index 16566a8902c..b6afda69198 100644 --- a/lisp/vc/vc-cvs.el +++ b/lisp/vc/vc-cvs.el @@ -1220,14 +1220,33 @@ is non-nil." "Return the administrative directory of FILE." (vc-find-root file "CVS")) -(defun vc-cvs-ignore (file &optional _directory _remove) - "Ignore FILE under CVS." - (vc-cvs-append-to-ignore (file-name-directory file) file)) - -(defun vc-cvs-append-to-ignore (dir str &optional old-dir) +(defun vc-cvs-ignore (file &optional directory _remove) + "Ignore FILE under CVS. +FILE is either absolute or relative to DIRECTORY. The basename +of FILE is written unmodified into the ignore file and is +therefore evaluated by CVS as an ignore pattern which follows +glob(7) syntax. If the pattern should match any of the special +characters ‘?*[\\\’ literally, they must be escaped with a +backslash. + +CVS processes one ignore file for each subdirectory. Patterns +are separated by whitespace and only match files in the same +directory. Since FILE can be a relative filename with leading +diretories, FILE is expanded against DIRECTORY to determine the +correct absolute filename. The directory name of this path is +then used to determine the location of the ignore file. The base +name of this path is used as pattern for the ignore file. + +Since patterns are whitespace sparated, it is usually better to +replace spaces in filenames with question marks ‘?’." + (setq file (directory-file-name (expand-file-name file directory))) + (vc-cvs-append-to-ignore (file-name-directory file) (file-name-nondirectory file))) + +(defun vc-cvs-append-to-ignore (dir str &optional old-dir sort) "In DIR, add STR to the .cvsignore file. If OLD-DIR is non-nil, then this is a directory that we don't want -to hear about anymore." +to hear about anymore. If SORT is non-nil, sort the lines of the +ignore file." (with-current-buffer (find-file-noselect (expand-file-name ".cvsignore" dir)) (when (ignore-errors @@ -1236,13 +1255,13 @@ to hear about anymore." (not (vc-editable-p buffer-file-name)))) ;; CVSREAD=on special case (vc-checkout buffer-file-name t)) - (goto-char (point-max)) - (unless (bolp) (insert "\n")) - (insert str (if old-dir "/\n" "\n")) - ;; FIXME this is a pcvs variable. - (if (bound-and-true-p cvs-sort-ignore-file) - (sort-lines nil (point-min) (point-max))) - (save-buffer))) + (goto-char (point-min)) + (save-match-data + (unless (re-search-forward (concat "^" (regexp-quote str) "$") nil 'move) + (unless (bolp) (insert "\n")) + (insert str (if old-dir "/\n" "\n")) + (if sort (sort-lines nil (point-min) (point-max))) + (save-buffer))))) (provide 'vc-cvs) -- 2.39.2