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

From: Wolfgang Scherer <[email-masked]>
Date: Thu, 13 Feb 2020 02:18:00 +0100

Hi Eli,

you must be using an Emacs < 27, if you get basenames in root/.gitignore, because that behavior changed with #37217:

> Only the basename of FILE is written to the ignore file. This is
> wrong for all filenames relative to project root with one ore
> more parent directories.
>
> The remove option is also implemented incorrectly.

I have totally forgotten, that I never really considered the "pattern"
use case you are so fond of, because the "file path" (vc-dir-ignore)
use case was so much more obvious to me.  Since I have fixed so much
of vc's shortcomings already, I have not really thought of the
original behavior until you asked me to show, why vc-ignore had always
been broken.

So, I just tried this in a Mercurial repository (it is fine to
use Git, as long as you can pretend that regular expressions are
valid wildcards):

1. Invoke vc-ignore `C-x v G`

2. Enter the correct regular expression for Mercurial (it is a
   wildcard for the VC according to your reasoning, is it not?):

   ^/some[/]sub

3. Check your .hgignore file and verify, that it only contains:

   ]sub

How is that behavior correct?  There should have been no change,
because the user is supposed to do everything themselves, right?

So how come, the correct documentation for vc-ignore before Emacs
27 is basically:

    (defun (vc-ignore FILE &optional DIRECTORY REMOVE)
      "...
    You will be prompted for an absolute file path, but don't think
    that it has any significance, because for Bzr, Git, Hg, Mnt:

    If you enter anything that ends with a slash, the string "./" is
    written into the nearest ignore file.

    Otherwise, everything up to and including the last slash is thrown
    away and the rest is written into the nearest ignore file.

    For CVS, whatever is entered is used as a filename to determine
    the directory of the ignore file. What ever was entered is then
    written entirely into that ignore file without modification, which
    makes no sense.

    For SVN, other strange things happen."

Applying `file-name-nondirectory` to an escaped pattern *never makes
any sense at all*, so why does it happen?

The simplest explanation is, that there is no "pattern" use case at
all. There is really only one use case, which is to ignore files by
pressing `G` in vc-dir-mode. The additional shortcut `C-x v G` for
vc-ignore is just there to make things symmetrical with other VC
commands like `i` and `C-x v i` and so forth.

That is also the reason why vc-ignore prompts for an absolute file
name. Because it is the exact same input it gets from
vc-dir-ignore. Case closed. vc-ignore does not have a pattern mode. It
was always broken entirely. Period.

So the implementation you are talking about has never existed, you are
just trying to somehow justify the broken behavior by making stuff up
and insisting that the behavior is intentional. Let me ensure you,
that it is not.

And if something is so utterly broken like the original vc ignore
feature, we are not talking about an API change but about a proper
refactoring to get it working at all. Any solution is better than no
solution.

I actually like the idea of a "pattern" input, so I am not sad about
the lost time. But I will now quit this absurd discussion of
non-existing algorithms and just keep working with my correct
implementation of the vc ignore feature.

Should you get your facts straight, we can talk further. Otherwise, I
have invested enough.time now.

Am 13.02.20 um 00:20 schrieb Wolfgang Scherer:
>>>> The old behavior of vc-ignore was not broken for interactive
>>>> invocations.  It was broken (in rare cases) for invocations from
>>>> vc-dir-ignore, and that can IMO be fixed without affecting user-facing
>>>> behavior.  So I see no backward-incompatible changes here.
>>> Sorry, not *rare* but **all** cases! The invocation from vc-dir-ignore
>>> placed an **absolute file path** into the ignore file.
>> That's not what I see, at least not with Git as the backend.  I see
>> only the basename of the file being added to the ignore file.
> Right, and that is incorrect for all cases, because it is
>
> 1. not anchored, i.e.it also matches files with the same name in
>    subdirectories,
> 2. if the basename comes from a file in a subdirectory, it also
>    matches files with the same name in the root directory.
>
> These reasons also apply to Bzr,Hg, Mtn, since the same functions are
> used. BTW, you are seeing these incorrect filenames so flawlessly,
> because I fixed the underlying functions in #37185 extensively.
>
> Originally, SVN at least got it right for files in the root directory,
> but none of the ignore specs for files in a subdirectory ever matched
> anything, which is probably better than matching the wrong thing..
>
>> Can you
>> show a use case where an absolute file name is written into the ignore
>> file by vc-dir-ignore?
> Yes, CVS is still broken in that manner, because the reviewer of
> #37215 thinks, that FILE is always a basename only.
>
> And there we are, *all* backend implementations fail utterly for
> vc-dir-ignore. Not just *rare*, but *almost all* cases (except root
> directory of SVN repo).
>