Subject: bug#37189: 25.4.1: vc-hg-ignore implementation is missing

From: Wolfgang Scherer <[email-masked]>
Date: Fri, 21 Feb 2020 23:22:18 +0100

Am 21.02.20 um 01:05 schrieb Dmitry Gutov:
> On 14.02.2020 11:23, Eli Zaretskii wrote:
>>> Cc: [email-masked]
>>> From: Dmitry Gutov <[email-masked]>
>>> Date: Fri, 14 Feb 2020 01:40:31 +0200
>>>
>>> I think the first thing I'll have to do is revert a part of an earlier
>>> patch to vc-default-ignore which changed its semantics a little, because
>>> it doesn't look like this discussion is going to culminate in a patch
>>> small enough for emacs-27 anyway.
>>
>> Which part?  Can you show a proposed patch?
>
> See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=37217.
>
> The patch fixed a legitimate scenario, but made an existing one work worse. Trying to vc-ignore, say, '*.c' from a subdirectory in a Git repo, for instance, will now prepend the intermediary directories to it.
>
> (Mentioned this before: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=37189#41)
>
> Now, one could argue that one use case is more important than the other one, and that vc-ignore has for a while been geared toward entering plain file names rather than glob patterns. I have little opinion on this subject, however, since I mostly edit ignore files by hand, and do so very rarely. So as far as I'm concerned, we could remove this feature altogether and not lose much.
Both use cases are important for casual users of a VC. Before this
research, I did not know anything about SVN, SRC, Bzr, Mtn. Ignore file
support in 'vc' as a distilled experience cache does come in handy,
even for experienced users. Especially, if escaping/anchoring is
implemented.
>
> But maybe it's more valuable for SVN users? Where the ignore configuration is more tricky and the DIRECTORY argument is actually important.
For SVN users it is extremely useful, since there are no files that
can be edited. Commands must be issued to store ignore
patterns. However, the commands cannot add patterns to existing
patterns, so the existing patterns have to be read and a new pattern
added, before writing everything back. That is pretty much work and
support by emacs as frontend is very valued.
>
> So the options at hand are:
>
> - Revert almost all of the patch from bug#37217, reverting to the previous, admittedly broken behavior, and continue to discuss a better improvement for Emacs 28.
I think that is the best way to proceed. The correct implementation is
definitely non-trivial and should not be made in a series of adhoc
patches.
> - Try to resolve the ambiguity of purpose in favor either entering patterns on file names only. Probably the latter, later vc-ignore to vc-ignore-file.
I have never seen the pattern feature before, but since I implemented
it now, I have come to realize that it is very useful, when combined
with pre-escaped and anchored patterns from the current file in
vc-dir-mode and dired-mode. It is extremely useful for regex pattern
syntax, where patterns are a lot more ambiguous and need more
attention than patterns with glob syntax.
> - Try to sit on both chairs... Basically, that means using the user input unaltered. Allowing them to enter a file name as well, but treat it as a pattern, without escaping or the like. This would be close to the original intent behind vc-ignore, AFAICT.
Pre-escaped and anchored is very useful. But unmodified ist a good
starting point.
> To do the last one, read-file-name would need to be called with the second argument provided, the directory against which the file path should be relative. For most backend, we can reuse the find-ignore-file backend command, but SVN (and RCS, etc) don't have it defined.
RCS, SCCS do not have ignore files, so they should error out. SRC has
ignore files similar to CVS and SVN. Do not forget that CVS and SVN
have functions vc-cvs-ignore and vc-svn-ignore, which are called
*instead* of vc-default-ignore. I.e. The changes to vc-default-ignore
do not affect those VCs. For the invocation of find-ignore-file in
vc-ignore, see below.
> Roughly and handwavy, we can take this case to mean "use default-directory".
Unfortunately not. If the file or pattern to be ignored is in a
subdirectory of default-directory, the DIRECTORY argument must reflect
this for CVS, SVN, SRC.
>
> As you noted, the use of read-file-name at all in vc-ignore is somewhat problematic, but let's see if we can keep the function sane without removing it first.
I would not change it for Emacs 27.
>
> Attaching a patch. Eli, Wolfgang, any objections?

As mentioned above, for CVS, SVN, SRC default-directory is not
necessarily the correct rel-dir. This would be better:

   (let* ((backend (vc-responsible-backend default-directory))
          (file (read-file-name "File to ignore: "))
          (rel-dir
           (condition-case nil
               (file-name-directory
                (vc-call-backend backend 'find-ignore-file
                                 default-directory))
             (vc-not-supported
              (file-name-directory
               (directory-file-name (expand-file-name file)))))))
     (when (and (file-name-absolute-p file)
                (file-in-directory-p file rel-dir))
       (setq file (file-relative-name file rel-dir)))
     (list file
           rel-dir
           current-prefix-arg)))

I apologize for introducing ewoc into vc-dir-mode. Meanwhile I have
discovered vc-deduce-fileset, which does all the hard work for
preparing a fileset in vc-dir-mode, dired-mode and other
modes. vc-deduce-fileset delivers a backend and absolute file names,
not relative file names. I think introducing relative file names in
function APIs is the wrong way to go. However, as a preliminary
solution, it does suffice.
>>> Then, naturally, we'll have to look for small changes that improve the
>>> situation but provide as little breakage as possible.
>>
>> Agreed.

Definitely.