git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [RFC] Define "precious" attribute and support it in `git clean`

From
Kristoffer Haugsbakk <code@khaugsbakk.name>
Date
Oct 11, 2023, 21:41 UTC
Message-ID
<b27782ce-8174-4d72-acc2-2d8f0e6e6ef1@app.fastmail.com>
In-Reply-To
<79901E6C-9839-4AB2-9360-9EBCA1AAE549@icloud.com>
On Tue, Oct 10, 2023, at 14:37, Sebastian Thiel wrote:
Show 13 quoted lines
> [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
Previous: Elijah Newren
Message 28 of 28 in “[RFC] Define "precious" attribute and support it in `git clean`”
  1. Sebastian ThielOct 10, 2023
  2. Kristoffer HaugsbakkOct 10, 2023
  3. Josh TriplettOct 10, 2023
  4. Junio C HamanoOct 10, 2023
  5. Josh TriplettOct 12, 2023
  6. Kristoffer HaugsbakkOct 10, 2023
  7. Josh TriplettOct 12, 2023
  8. Junio C HamanoOct 10, 2023
  9. Richard KerryOct 11, 2023
  10. Jeff KingOct 11, 2023
  11. Junio C HamanoOct 11, 2023
  12. Sebastian ThielOct 12, 2023
  13. Junio C HamanoOct 12, 2023
  14. Sebastian ThielOct 13, 2023
  15. Junio C HamanoOct 13, 2023
  16. Sebastian ThielOct 14, 2023
  17. Phillip WoodOct 13, 2023
  18. Junio C HamanoOct 14, 2023
  19. Oswald BuddenhagenOct 13, 2023
  20. Josh TriplettOct 14, 2023
  21. Junio C HamanoOct 14, 2023
  22. Elijah NewrenOct 15, 2023
  23. Sebastian ThielOct 15, 2023
  24. Junio C HamanoOct 15, 2023
  25. Sebastian ThielOct 16, 2023
  26. Sebastian ThielOct 23, 2023
  27. Elijah NewrenOct 29, 2023
  28. Kristoffer HaugsbakkOct 11, 2023

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.