On Tue, Oct 10, 2023, at 14:37, Sebastian Thiel wrote: > [Note: I'm collaborating with Josh Triplett (CCed) on the design.] > > I'd like to propose adding a new standard gitattribute "precious". I've > included proposed documentation at the end of this mail, and I'm happy to write > the code. I wanted to get feedback on the concept first. > > What's a 'precious' file? > > "Precious" files are files that are specific to a user or local configuration > and thus not tracked by Git. As such, a user spent time to create or generate > them, and to tune them to fit their needs. They are typically also ignored by > `git` due to `.gitignore` configuration, preventing them to be tracked by > accident. How do people deal with these precious files today? You could track these precious files somewhere else. Maybe a Git directory which is a sibling of `.git`. .git-local Files that are useless to the project but important to the individual. It would get its own “excludes” file. .gitignore-local Now the normal repository (`.git`) needs to ignore these things. # Cast a wide net: could want other siblings # Use another pattern if you have something like `.git-blame-ignore-revs` printf '.git-*\n' >> .git/info/exclude printf '.gitignore-*\n' >> .git/info/exclude You need to pass in two arguments to `git` every time you want to use `.git-local`. alias gitl='git --git-dir=.git-local -c core.excludesFile=.gitignore-local' Git Local should ignore everything by default. You should check with `.gitignore` to make sure that it ignores the files that Git Local does _not_ ignore. printf '*\n' >> .gitignore-local printf '!.gitignore-local\n' >> .gitignore-local printf '!.idea/**\n' >> .gitignore-local Now you can backup your local files. gitl add .gitignore-local gitl add .idea gitl commit -m'Update local' But you can also version control them by providing real (intentional) messages. (Maybe `.idea/` is just an XML soup and thus hard to make a VCS narrative around; I don't know yet.) `git clean` won't help you. But an alias can. Or if writing a shell-oneliner alias is too hard for you, I mean me. #!/bin/sh # git-klean git --git-dir=.git-local -c core.excludesFile=.gitignore-local add --all git --git-dir=.git-local -c core.excludesFile=.gitignore-local commit -mUpdate git clean -e .gitignore-local -e .git-local "$@" The two `-e` switches protect the Git Local things from being wiped by `-xd` (tested with `--dry-run`). § Sibling repositories At first I thought that `git clean` could use a `pre-clean` hook. But that's not very satisfying. Maybe Git could be told about its siblings via a multi-valued configuration variable. sibling=local Then it expects there to exist `.git-<sibling name>` repository next to it (`.git/../.git-<sibling name>`). Then the rule becomes: Only do destructive operations if all of the working trees[1] of the sibling repositories are clean (cannot override with `--force`). Additionally one could say that directories that are Git repositories should be ignored by `git clean`, always.[2] Or siblings which match the glob: .git-* ... Or if you want something longer: .git-sibling-* (And also ignore `.gitignore-*` and maybe more things) Then the regular Git repository might still blow away your precious files. But they will be backed up by the siblings. Or you put these other Git repositories outside of `.git/..`. Sidestepping the issue at the cost of some path confusion (for yourself). Maybe at: /home/user/git-siblings/repository1/local † 1: Worktrees not considered. † 2: And what would that break? People who make Git repositories in their working trees and then delete them? (Well they can still use `rm -r`.) ⧫ ⧫ § Worktrees But seriously: worktrees probably makes this not work. -- Kristoffer