On Tue, Oct 10, 2023 at 10:02:20AM -0700, Junio C Hamano wrote: > Sebastian Thiel <sebastian.thiel@xxxxxxxxxx> writes: > > > I'd like to propose adding a new standard gitattribute "precious". > > ;-). > > Over the years, I've seen many times scenarios that would have been > helped if we had not just "tracked? ignored? unignored?" but also > the fourth kind [*]. The word "ignored" (or "excluded") has always > meant "not tracked, not to be tracked, and expendable" to Git, and > "ignored but unexpendable" class was missing. I even used the term > "precious" myself in those discussions. At the concept level, I > support the effort 100%, but as always, the devil will be in the > details. "I've already wanted this for years" is, honestly, the best response we could *possibly* have hoped for. > Scenarios that people wished for "precious" traditionally have been > > * You are working on 'master'. You have in your .gitignore or > .git/info/exclude a line to ignore path A, and have random > scribbles in a throw-away file there. There is another branch > 'seen', where they added some tracked contents at path A/B. You > do "git checkout seen" and your file A that is an expendable file, > because it is listed as ignored in .git/info/exclude, is removed > to make room for creating A/B. Ouch, I hadn't even thought about the issue of branch-switching overwriting a file like that, but that's another great reason to have "precious". (I've been thinking about "precious" as primarily to protect files like `.config`, where they'd be unlikely to be checked in on any branch because they have an established purpose in the project. Though, of course, people *do* sometimes check in `.config` files in special-purpose branches that aren't meant for upstreaming.) > * Similar situation, but this time, 'seen' branch added a tracked > contents at path A. Again, "git checkout seen" will discard the > expendable file A and replace it with tracked contents. > > * Instead of "git checkout", you decide to merge the branch 'seen' > to the checkout of 'master', where you have an ignored path A. > Because merging 'seen' would need to bring the tracked contents > of either A/B (in the first scenario above) or A (in the second > scenario), your "expendable" A will be removed to make room. +1 > In previous discussions, nobody was disturbed that "git clean" was > unaware of the "precious" class, but if we were to have the > "precious" class in addition to "ignored" aka "expendable", I would > not oppose to teach "git clean" about it, too. > > There was an early and rough design draft there in > > https://lore.kernel.org/git/7vipsnar23.fsf@xxxxxxxxxxxxxxxxxxxxxxxx/ > > which probably is worth a read, too. > > Even though I referred to the precious _attribute_ in some of these > discussions, between the attribute mechanism and the ignore > mechanism, I am actually leaning toward suggesting to extend the > exclude/ignore mechanism to introduce the "precious" class. That > way, we can avoid possible snafu arising from marking a path in > .gitignore as ignored, and in .gitattrbutes as precious, and have to > figure out how these two settings are to work together. Sounds reasonable. > In any case, the "precious" paths are expected to be small minority > of what people never want to "git add" or "git commit", so coming up > with a special syntax to be used in .gitignore, even if that special > syntax is ugly and cumbersome to type, would be perfectly OK. [Following up both to this and to Sebastian's response.] One potentially important question: should the behavior of old git be to treat precious files as ignored, or as not-ignored? If the syntax were something like $.config then old git would treat the file as not-ignored. If the syntax were something like $precious .config then old git would treat the file as ignored. Seems like it would be obtrusive if `git status` in old git showed the file, and `git add .` in old git added it.