git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Sebastian Thiel <sebastian.thiel@icloud.com>
To: Junio C Hamano <gitster@pobox.com>
Cc: git@vger.kernel.org, Josh Triplett <josh@joshtriplett.org>,
	Kristoffer Haugsbakk <code@khaugsbakk.name>
Subject: Re: [RFC] Define "precious" attribute and support it in `git clean`
Date: Thu, 12 Oct 2023 12:55:19 +0200	[thread overview]
Message-ID: <0E44CB2C-57F2-4075-95BE-60FBFDD3CEE2@icloud.com> (raw)
In-Reply-To: <xmqqttqytnqb.fsf@gitster.g>

I liked the idea too see precious files as sub-class of ignored files, and
investigated possibilities on how to achieve that while keeping the overall
effort low and remove any potential for backwards-incompatibility as well.

Currently, `.gitignore` files only contain one pattern per line, which
optionally may be prefixed with `!` to negate it. This can be escaped with `\!`
- and that's it.

Parsing patterns that way makes for simple parsing without a need for
quoting.

### What about a `$` syntax in `.gitignore` files?

I looked into adding a new prefix, `$` to indicate the following path is
precious or… valuable. It can be escaped with `\$` just like `\!`. 

Doing so has the advantage that older `git` versions simply take the
declaration as literal and would now exclude `$.config`, for example, whereas
newer `git` versions will consider them precious.

There is some potential for accidentally excluding files that previously
were untracked with older versions of git, but I'd think chances are low.

#### Example: Linux kernel

`.config` is ignored via `.gitignore: 

    .*

*Unfortunately*, users can't just add a local `.git/info/exclude` file with
`$.config` in it and expect `.config` to be considered precious as the pattern
search order will search this last as it's part of the exclude-globals. The
same is true for per-user git-ignore files. This means that any git would
have the `.*` pattern match before the `$.config` pattern, and stop right there
concluding that it's expendable, instead of precious. This is how users can
expect `.gitignore` files to work, and this is how `!negations` work as well -
the negation has to come after the actual exclusion to be effective.

Thus, to make this work, projects that ship the `.gitignore` files would *have
to add patterns* that make certain files precious.

Alternatively, users have to specify gitignore-overrides on the command-line,
but not all commands (if any except for `git check-ignore`) support that.

In the case of `git clean` one can already pass `--exclude=pattern`, but if
that's needed one doesn't need syntax for precious files in the first place.

**This makes the $precious syntax useful only for projects who chose to opt in,
but makes overrides for users near impossible**.

Such opted-in projects would produce `.gitignore` files like these:

    .*
    $.config

Note that due to the way ignore patterns are searched, the following would
consider `.config` trackable, not precious:

    .*
    $.config
    !.config

It's up the maintainer of the repository to configure their .gitignore files
correctly, so nothing new either.

#### Benefits

* simple implementation, fast
* backwards compatible

#### Disadvantages

* cannot easily be overridden by the user as part of their local settings.
* needs repository-buy-in to be useful
* $file could clash with the file '$file' and cause older git  to ignore it

### What about a `precious` attribute?

The search of `.gitattributes` works differently which makes it possible for
users to set attributes on any file or folder easily using their local files.
Using attributes has the added benefit of being extensible as one can start out
with:

```gitattributes
.config precious
```

and optionally continue with…

```gitattributes
.config precious=input
kernel precious=output
```

…to further classify kinds of precious files, probably for their personal use.
Please note that currently pathspecs can't be used to filter by attribute
for files that are igonred and untracked or I couldn't figure out how.
That even makes sense as it wasn't considered a use-case yet.


#### Benefits

* backwards compatible
* easily extendable with 'tags' or sub-classes of precious files using the
  assignment syntax.
* overridable with user's local files

#### Disadvantages

* any 'exclude' query now also needs a .gitattribute query to support precious
  files (and it's not easy to optimize unless there is a flag to turn precious
  file support on or off)
* `precious` might be in use by some repos which now gains a possibly different
  meaning in `git` as well.

### Conclusion

Weighing advantages and disadvantages of both approaches makes me prefer the
`.gitignore` extension. The `.gitattributes` version of it *could* also be
implemented on top of it at a later date. However, it should be gated behind a
configuration flag so users who need it as they want local overrides
can opt-in. Then they also pay for the feature which for most repositories 
won't be an issue in the first place.

All this seems a bit too good to be true, and I hope you can show where
it wouldn't work or which dangers or possible issues haven't been
mentioned yet.


  parent reply	other threads:[~2023-10-12 10:56 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-10 12:37 [RFC] Define "precious" attribute and support it in `git clean` Sebastian Thiel
2023-10-10 13:38 ` Kristoffer Haugsbakk
2023-10-10 14:10   ` Josh Triplett
2023-10-10 17:07     ` Junio C Hamano
2023-10-12  8:47       ` Josh Triplett
2023-10-10 19:10     ` Kristoffer Haugsbakk
2023-10-12  9:04       ` Josh Triplett
2023-10-10 17:02 ` Junio C Hamano
2023-10-11 10:06   ` Richard Kerry
2023-10-11 22:40     ` Jeff King
2023-10-11 23:35     ` Junio C Hamano
2023-10-12 10:55   ` Sebastian Thiel [this message]
2023-10-12 16:58     ` Junio C Hamano
2023-10-13  9:09       ` Sebastian Thiel
2023-10-13 16:39         ` Junio C Hamano
2023-10-14  7:30           ` Sebastian Thiel
2023-10-13 10:06       ` Phillip Wood
2023-10-14 16:10         ` Junio C Hamano
2023-10-13 11:25       ` Oswald Buddenhagen
2023-10-14  5:59   ` Josh Triplett
2023-10-14 17:41     ` Junio C Hamano
2023-10-15  6:44     ` Elijah Newren
2023-10-15  7:33       ` Sebastian Thiel
2023-10-15 16:31         ` Junio C Hamano
2023-10-16  6:02           ` Sebastian Thiel
2023-10-23  7:15           ` Sebastian Thiel
2023-10-29  6:44             ` Elijah Newren
2023-10-11 21:41 ` Kristoffer Haugsbakk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0E44CB2C-57F2-4075-95BE-60FBFDD3CEE2@icloud.com \
    --to=sebastian.thiel@icloud.com \
    --cc=code@khaugsbakk.name \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=josh@joshtriplett.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).