From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Wolfgang Scherer Newsgroups: gmane.emacs.bugs Subject: bug#37189: 25.4.1: vc-hg-ignore implementation is missing Date: Mon, 3 Feb 2020 02:16:43 +0100 Message-ID: References: <1ba53ae2-42a4-3ab3-d4f2-2ceae565d198@gmx.de> <52917e6f-2f00-25cf-4353-dfb40287d0ea@gmx.de> <83pnkrdpb3.fsf@gnu.org> <679942e8-abe9-b0fc-720d-75a54d8d0b5a@gmx.de> <95da41e8-7a55-a15c-cfa7-d70366f9ee6b@gmx.de> <412195c1-e196-12af-933b-0312f5075847@yandex.ru> <57825d73-27a4-d5f5-8198-a172796a558a@gmx.de> <1ebc6077-9175-65ba-4996-282bb2c8eca5@yandex.ru> <6145d6f6-37a8-7166-731b-57669086b145@gmx.de> <838slmk90j.fsf@gnu.org> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="52257"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.9.1 Cc: 37189@debbugs.gnu.org, dgutov@yandex.ru To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Mon Feb 03 02:17:34 2020 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1iyQMo-000DQd-MZ for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 03 Feb 2020 02:17:34 +0100 Original-Received: from localhost ([::1]:32818 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iyQMn-0005Ad-Bm for geb-bug-gnu-emacs@m.gmane-mx.org; Sun, 02 Feb 2020 20:17:33 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:46357) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iyQMK-0005AL-Tq for bug-gnu-emacs@gnu.org; Sun, 02 Feb 2020 20:17:06 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iyQMI-0005lS-Qp for bug-gnu-emacs@gnu.org; Sun, 02 Feb 2020 20:17:04 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:34795) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iyQMI-0005lL-NS for bug-gnu-emacs@gnu.org; Sun, 02 Feb 2020 20:17:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1iyQMI-0002Be-JG for bug-gnu-emacs@gnu.org; Sun, 02 Feb 2020 20:17:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Wolfgang Scherer Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 03 Feb 2020 01:17:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 37189 X-GNU-PR-Package: emacs Original-Received: via spool by 37189-submit@debbugs.gnu.org id=B37189.15806926148389 (code B ref 37189); Mon, 03 Feb 2020 01:17:02 +0000 Original-Received: (at 37189) by debbugs.gnu.org; 3 Feb 2020 01:16:54 +0000 Original-Received: from localhost ([127.0.0.1]:40768 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iyQM9-0002BF-FM for submit@debbugs.gnu.org; Sun, 02 Feb 2020 20:16:54 -0500 Original-Received: from mout.gmx.net ([212.227.15.15]:36723) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iyQM6-0002B2-Tr for 37189@debbugs.gnu.org; Sun, 02 Feb 2020 20:16:51 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1580692604; bh=oKtl//DFxDTWxc0XZnmklkciQgBdTAKhg0vRh69eXDI=; h=X-UI-Sender-Class:Subject:To:Cc:References:From:Date:In-Reply-To; b=dQkuxzVYTkxozTOaxC6if2z1/qwfWEIcJY6C2FL4rVgvJjJxmj9QevrvEzNzqyBK/ LMtO1zX7+HE55+zrLruEYvaCoUC22I9lOn1oJpxBFcSsHBvGT59KgIH8CsSHFmY5Y6 ZYL4Apa5Hw0CvsmL/BMQRHRjZZoHtXefkljjDri0= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Original-Received: from sheckley.simul.de ([87.160.210.52]) by mail.gmx.com (mrgmx004 [212.227.17.190]) with ESMTPSA (Nemesis) id 1MLzFr-1jFgDt1YW1-00Hx5P; Mon, 03 Feb 2020 02:16:44 +0100 Original-Received: from [127.0.0.1] (sheckley.simul.de [127.0.0.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by sheckley.simul.de (Postfix) with ESMTPSA id 505F81943155; Mon, 3 Feb 2020 02:16:43 +0100 (CET) Openpgp: preference=signencrypt Autocrypt: addr=Wolfgang.Scherer@gmx.de; prefer-encrypt=mutual; keydata= xsDiBEb46IgRBACMHOAb1KNo1Ylk+ebri+4R+bG4tyKlqBlrpv8D9/ZwRdXSGt+0DyCHoaAd 7KW7noHapLe87DunABOjKG4nqTGv+dRiWuUBlp3I4aYRFDVa3Da+XnIYkMHKqhK59VEHQCdp Km42nuLS7TS+n99at9YwzTG6VBdOlBKTlRFngOjVLwCg1RGXJ6X3EjS1FKCQeXziURVpWlkD /2zY6Ayhxi62TS84VjikXrrmjXykAAaAmMVEyKKYb9L5pGlqiZz9g/K9xw1EUoZTYuaufquD v4rAGR58K/3V4CYfJLEeshMWiaXHvMmlxMznlG16/um4MvmR8B3r+cx0nOPK1JBdD2qrkNnF Mw8FB+zouLFB4Gt2IUC5IlOmZ8OQA/4qdU53CItzWsCr9Nux4L0qUlRweSmCnV8xGQ2wP5XI MawIQxxREvSrsYDG8cNnYETMg4iQFfIktwAoxCJvuFAwIB6ZxHGF4FcEZm64CXc2u7CmFLqt rVhXhIfMz9oEYC+HhGczGamn9ofbGTFd2hJEtPcQgWNR4f7+aKknmi2+OM0fV29sZmdhbmcg U2NoZXJlciA8d3NAc3ctYW10LndzPsJhBBMRAgAhBQJYmz3YAhsjBQsJCAcCBhUICQoLAgQW AgMBAh4BAheAAAoJEIUCr3Gr112VZZoAoLTBSTp1qGuNhLdXY04iaWCMYmHCAJ4kHPtQ6nTw kEq9qCHgVgXDaY7wjs7ATQRG+OiIEAQAhi0wjcxvA4tychg2NQuwBIf9LX/46l+74+QbewCn a4a+mw/9s5KY In-Reply-To: <838slmk90j.fsf@gnu.org> Content-Language: de-DE X-Provags-ID: V03:K1:4nHm6Y7vn1Pk32tNNkn2xGoHFUaiF0/1qrcImE0Y+QKXKbRHjEb jFQ2wi38mRI7JzQfqdg4zYY8GXnrmWq7UVeQfmQe+/HTZw4BhwKrTPYc3TuhQlP+p87Elv0 mOLLhaQmmt07c86fDW13HHJ7zjLv8vUNivxYnznGa+2w8xyCnSX6iex+UHIxOd0quzRh7ay MoasurGZozWcuwFj7ox1A== X-UI-Out-Filterresults: notjunk:1;V03:K0:gbV+TOOWpeM=:G+1IDdVJyC78RR+8Th2c5y FbapbmlU9lSxWjVcaRM5t3pT776gGo5XvMGSLXqxWrIWSSn7bDQHGzE/TLsedqkhAmbWttuth gxbv/+BtKsK19ayER9aIH0YZD1h5ZxrsIQ0NcKbTciLYhbqYuS4DOujpsPy9TqLVvnO1Jzcic ZzVwqo2Hk9tIPuKgTovLeJGdmCzPOtb7AqCRjzkM9ioyxxiEm8a9TSUqV0xj/NGC/A+5RZ00n WX5Bitn8yPXaYxK6DGzxesBaH/wlaBOAm4JifB78QmAGQix8cCkNWnoQ2wZgDNt6Z1NQ2ixYg QuQtdQ1bYZ0Huc3YUIaAVdgdjWbJqx8S/p6aIqDw3+c6XAIYwGtUqvPI0qf/1bHl8kAjtDs2B LVjW+Xu8VcUm/ni2QPoWLYA/Zz/tjYwveSNYPAuPY4HTUtoLBRBHpFljO3ue0mUVJETwUVXQz wblNDCMbVHVldafGQ1DPO3sS8kEc7GqoZyr7jJNgsuELx++OE3NYfoe3M2ZL/aeHhYnzIEWJy b6SywLa3Pk8bTG25X+Q3wCONNI/L/UQg5redDXlDsalb5ju1lM9J+xBEJKvvPVM9/KKIQhDl6 PheMzvUDMJ41NrduCWbtCyzZejfA0p8rGtIkOPE+PvMAuQkficRiYHwWx5IlXNFzCqh6XBKUa Dyw/YqF/F6tha5VNO1wSfGAg0ZOnThWbURBLPU1FHUTPsTv5oqkQtEbN5hp0+mRxDKCf645mX PKET9ep9o7+n/WX+Qpti70Csqr5mEb4sVVB7YGaS3NXxFO/aQ9Mmbqi1GQMOMZdphZ6ivssO X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:175623 Archived-At: Am 01.02.20 um 09:27 schrieb Eli Zaretskii: >> From: Wolfgang Scherer >> Date: Sat, 1 Feb 2020 02:20:08 +0100 >> >> I don't think, that the problem with ignore specs can be solved in >> this (adhoc) manner. It should (finally) be properly designed. >> >> There is a fundamental difference between per-directory ignore specs >> and per-tree ignore specs. Let me try to outline, where I see the >> problem with the current implementation: >> >> 1. Per-tree VC support is (unecessarily) mapped onto per-directory >> =C2=A0=C2=A0 semantics. >> 2. `vc-ignore` is a quick and dirty afterthought, which does not >> =C2=A0=C2=A0 properly model per-tree use cases. >> 3. The rationale for my implementation of `vc-hg-ignore` covers >> =C2=A0=C2=A0 several use cases, which should be considered for a proper= design. > Could you please elaborate on these 3 points? I've read the rest of > your message at least twice, and I still don't think I understand your > POV on these 3 issues well enough to make up my mind about them. I > appreciate the overview of the history of these features -- it might > very well help us understand your POV -- but the POV itself is not > clearly presented, AFAICT, so I at least couldn't find a path from the > history of these features to the problems you allude to. And the > history alone cannot explain the problems in the current design, > because there's nothing wrong in evolving a design per se. > > IOW, I'm OK with discussing design issues of ignoring files in VC, but > please let's begin by presenting clear and detailed descriptions of > the problems in the current design, and why you think the current > design cannot easily support valid use cases with modern VCSes. > > Thanks. Well, I will try again. Opening a can of worms =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Just to be clear that my original intention was only a simple bugfix ... In order to phase out `dvc`, I tried to use `vc-dir-ignore` in a Mercurial repository. At that time (2019-08-24) I was still using emacs 24.5 and 25.4.1 ubuntu standard packages. First I ran into an unrelated bug with marking files in `vc-dir-mode`. So, I cloned the current emacs repository to see, whether that bug was already fixed. Since it was not, I decided to report it (see bug #37182 https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D37182). While implementing `vc-hg-ignore`, I found the implementations of `vc--add-line`, `vc--remove-regexp` faulty, which lead to bug #37185 https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D37185. Now I started using Emacs snapshot packages (v26.3). After finishing `vc-hg-ignore` in bug Bug #37189 https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D37189, I checked the implementation of other VCSs that I still use (CVS, SVN, GIT) and found them non-functional: - CVS bug #37215 https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D37215 - SVN bug #37214 https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D37214, =C2=A0 bug #37216 https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D37216 - GIT does not have a specialized backend version, so I circled back =C2=A0 to `vc-default-ignore`, which ironically would have worked for CVS, =C2=A0 but not for per-tree semantics. The resulting patch in bug #37217 =C2=A0 https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D37217 implements =C2=A0 minimal per-tree functionality, but should be specialized for Git =C2=A0 ignore glob features (anchored glob patterns). There was no provision in `vc-dir-ignore` to ignore all marked files, which begat bug #37240 https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D37240. The discussion about my adhoc implementation of `vc-hg-ignore` now ends up in a design analysis. How funny :-). This discussion and the latest discovery (bug #39380 https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D39380) finally sparked the historic research into the `vc` package. The research does show, that the initial implementation started out with per-directory semantics. Although the `vc-default-ignore` function was designed to cover Git/Hg in an adhoc manner, it was never properly implemented. The amount of bugs further shows, that the ignore feature was never properly integrated. Per-directory vs. per-tree =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Per-directory and per-tree ignore contexts are sufficently polymorphic such that per-directory algorithms can easily be implemented on top of per-tree algorithms. However, implementing per-tree behavior on top of per-directory does not generally work. While there is no **difference between filepath and file pattern** in a per-directory glob context, the difference **becomes vital in a per-tree context**. The difference is further acerbated, when patterns are encoded as regular expressions. Since there is no possible automatic detection of filepath vs. file pattern, the current API of `vc-ignore` is insufficient. Ignoring existing files leads to patterns with the least amount of ambiguity, which requires regular expressions to be escaped. Whereas user supplied patterns should not be encoded at all. The use cases 1, 2, 3 below should therefore be covered by `vc-ignore-file`, use case 4 should be covered by `vc-ignore-pattern`. `vc-ignore` should be expanded to accept an optional flag `as-is` which determines processing of the `file` argument. This flag can be used by `vc-ignore-pattern` to specify its use case. `vc-ignore-file` can be implemented as alias for `vc-ignore`. Per-directory =2D------------ Per-directory `vc-ignore` algorithm for CVS: - One ignore file per directory. - Each line is a file glob pattern relative to the directory of the ignore= file. - Pattern scope is limited to the directory. Use cases 1. Ignore a file in `vc-dir-mode`. =C2=A0=C2=A0 Write basename of absolute filepath into ignore file for dire= ctory. 2. Ignore marked files in `vc-dir-mode`. =C2=A0=C2=A0 Write basename of relative filepath into ignore file for dire= ctory. 3. Ignore absolute/relative filepath with `vc-ignore`. =C2=A0=C2=A0 Write basename of filepath into ignore file for directory. 4. Ignore pattern with `vc-ignore`. =C2=A0=C2=A0 Write pattern unaltered into ignore file of directory. Per-tree =2D------- Per-tree algorithms for Mercurial (Git is somewhat similiar, but only supports glob patterns): - Single ignore file at the root of the repository - alternative syntax: regexp or glob - Each line is a pattern for a filepath relative to the directory of the i= gnore file. - Pattern scope extends into sub directories 1. Ignore a file in `vc-dir-mode`. =C2=A0=C2=A0 Convert absolute filepath to filepath relative to `vc-root-di= r` and write into ignore file. 2. Ignore marked files in `vc-dir-mode`. =C2=A0=C2=A0 Convert filepath relative to default directory to filepath re= lative to `vc-root-dir` and write into ignore file. 3. Ignore absolute/relative filepath with `vc-ignore`. =C2=A0=C2=A0 Convert filepath to filepath relative to `vc-root-dir` and wr= ite into ignore file. 4. Ignore pattern with `vc-ignore`. =C2=A0=C2=A0 Write pattern unaltered into ignore file. Faulty implementation of `vc-default-ignore` =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Both sets of algorithms and use cases are currently covered by `vc-ignore` being called interactively or by `vc-dir-ignore` from `vc-dir-mode`. The reference backend implementation is `vc-default-ignore`. Although the documentation already specifies what the function should do in a per-tree context, the original implementation strangely follows the description of `vc-ignore` which is still per-directory. Consequently the original implementation of `vc-default-ignore` only works for per-directory VCSs. This would have been sufficient for CVS, but ironically CVS has a specialized function `vc-cvs-ignore`, imported from `pcvs`, which does not work correctly . While the frontend command `vc-ignore` does not have inherent per-directory or per-tree semantics, the description should use a per-tree context, similar to `vc-default-ignore`. A. Original vc-default-ignore =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D .. code-block:: elisp =C2=A0=C2=A0 (defun vc-default-ignore (backend file &optional directory re= move) =C2=A0=C2=A0=C2=A0=C2=A0 "Ignore FILE under the VCS of DIRECTORY (default = is `default-directory'). =C2=A0=C2=A0 FILE is a file wildcard, relative to the root directory of DI= RECTORY. =C2=A0=C2=A0 When called from Lisp code, if DIRECTORY is non-nil, the =C2=A0=C2=A0 repository to use will be deduced by DIRECTORY; if REMOVE is =C2=A0=C2=A0 non-nil, remove FILE from ignored files. =C2=A0=C2=A0 Argument BACKEND is the backend you are using." =C2=A0=C2=A0=C2=A0=C2=A0 (let ((ignore =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (vc-cal= l-backend backend 'find-ignore-file (or directory default-directory))) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (pattern (fil= e-relative-name =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (expand-file-name file) (= file-name-directory file)))) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (if remove =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (vc--remove-r= egexp pattern ignore) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (vc--add-line pattern ign= ore)))) B. Revised vc-default-ignore =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D .. code-block:: elisp =C2=A0=C2=A0 (defun vc-default-ignore (backend file &optional directory re= move) =C2=A0=C2=A0=C2=A0=C2=A0 "Ignore FILE under the VCS of DIRECTORY (default = is `default-directory'). =C2=A0=C2=A0 FILE is a wildcard specification, either relative to =C2=A0=C2=A0 DIRECTORY or absolute. =C2=A0=C2=A0 When called from Lisp code, if DIRECTORY is non-nil, the =C2=A0=C2=A0 repository to use will be deduced by DIRECTORY; if REMOVE is =C2=A0=C2=A0 non-nil, remove FILE from ignored files. =C2=A0=C2=A0 Argument BACKEND is the backend you are using." =C2=A0=C2=A0=C2=A0=C2=A0 (let ((ignore =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (vc-cal= l-backend backend 'find-ignore-file (or directory default-directory))) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 file-path roo= t-dir pattern) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (setq file-path (expand-file-name fil= e directory)) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (setq root-dir (file-name-directory i= gnore)) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (when (not (string=3D (substring file= -path 0 (length root-dir)) root-dir)) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (error "Ignore spec %s is= not below project root %s" file-path root-dir)) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (setq pattern (substring file-path (l= ength root-dir))) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (if remove =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (vc--remove-r= egexp (concat "^" (regexp-quote pattern ) "\\(\n\\|$\\)") ignore) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (vc--add-line pattern ign= ore)))) C. vc-ignore =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D .. code-block:: elisp =C2=A0=C2=A0 (defun vc-ignore (file &optional directory remove) =C2=A0=C2=A0=C2=A0=C2=A0 "Ignore FILE under the VCS of DIRECTORY. =C2=A0=C2=A0 Normally, FILE is a wildcard specification that matches the f= iles =C2=A0=C2=A0 to be ignored.=C2=A0 When REMOVE is non-nil, remove FILE from= the list =C2=A0=C2=A0 of ignored files. =C2=A0=C2=A0 DIRECTORY defaults to `default-directory' and is used to =C2=A0=C2=A0 determine the responsible VC backend. =C2=A0=C2=A0 When called interactively, prompt for a FILE to ignore, unles= s a =C2=A0=C2=A0 prefix argument is given, in which case prompt for a file FIL= E to =C2=A0=C2=A0 remove from the list of ignored files." =C2=A0=C2=A0=C2=A0=C2=A0 (interactive =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (list =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (if (not current-prefix-arg) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (read-file-na= me "File to ignore: ") =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (completing-read =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "File to remove: " =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (vc-call-backend =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (or (vc-respo= nsible-backend default-directory) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0 (error "Unknown backend")) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 'ignore-compl= etion-table default-directory))) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 nil current-prefix-arg)) =C2=A0=C2=A0=C2=A0=C2=A0 (let* ((directory (or directory default-directory= )) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (backen= d (or (vc-responsible-backend default-directory) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (= error "Unknown backend")))) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (vc-call-backend backend 'ignore file= directory remove)))