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.
This commit is contained in:
Wolfgang Scherer 2020-02-21 21:28:11 +01:00 committed by Eli Zaretskii
parent d7c22338d2
commit 0273f261a7
2 changed files with 33 additions and 14 deletions

View file

@ -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))

View file

@ -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-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.
(defun vc-cvs-append-to-ignore (dir str &optional old-dir)
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)