threads / discuss / 63847

Subject: [RFC] Add config option to enforce committing .gitignore / .gitattributes before other files

Subject: Subject: [RFC] Add config option to enforce committing .gitignore / .gitattributes before other files

## tl;dr

3 messages between Jul 25, 2025 and Jul 26, 2025.

replies: 2people: 3as markdown or json

Kirill Sploshnov· Jul 25, 2025, 10:40 UTC · lore
Hi Git community,

I’d like to propose a new optional safety feature in Git related to .gitignore and .gitattributes handling.

[Problem Statement]

Some software ecosystems - such as game development tools (Unity, Unreal Engine) and other project-based environments - rely on predefined project folders that include .gitignore and .gitattributes. These files:

- Exclude large generated files, build caches, and temporary data.
- Configure Git LFS for specific binary asset types.

To minimize interference with the rest of a repository, these files are often shipped inside each project folder, not at the repo root. This allows multiple projects or heterogeneous formats to coexist.

However, Git only applies ignore and attribute rules after these files are staged or committed. In practice, many users copy a project into an existing repo and immediately run:

> git add .

This stages everything - including an arbitrarily large cache or binaries that should have been excluded or redirected to LFS. This causes:

- Bloated history and additional cleanup.
- LFS pointer issues and git workflow disruptions ("encountered files
that should've pointers but weren't" errors for other repo users).
This problem is especially common when:
- Teams copy/import projects frequently.
- Team members include non-engineering roles (artists, designers).
- Tight schedules or manipulation of large amounts of small projects
daily make careful staging problematic.
[Proposed Solution]

Introduce an optional config that requires .gitignore and .gitattributes to be committed before other files:

> [commit]
>     requireIgnoreFirst = true
[Behaviour]
- If the option is set to true and ANY .gitignore or .gitattributes
differ from HEAD (newly added or has changes) and other files are
staged in the same commit THEN the commit fails.
- Enforcement happens at git commit (not git add) to minimize disruption.
- Error message includes a ready-to-use fix:
> Error: .gitignore and / or .gitattributes changes detected and must be committed before committing other files. Please commit them separately first, before adding other changes:
> git reset && git add <path to .gitignore> && git add <path to .gitattributes> && git commit -m <commit message>

The idea is motivated by the [pre-commit](https://pre-commit.com/), the de-facto standard extension to use for git hooks managements - it behaves similarly, forbidding to commit anything if .pre-commit-config.yaml has any changes, requiring it to be committed first to avoid inconsistencies.

P.S.: this option could potentially be extended to include not just predefined paths but a list of patterns in a [.gitignore pattern format](https://git-scm.com/docs/gitignore#_pattern_format), but I see little incentive to have this customizable as of now - can be discussed, but the simpler suggested option should be sufficient for all cases.

Benefits
- Prevents accidental commits of caches or binary artifacts.
- Reduces Git LFS misconfiguration disruptions.
- Minimal intrusion - one local config setting. May be set up globally
for companies / users with many repos.
- Easy to advocate as a solution for the given software product users.
- Zero assumptions about any repo layout or user's local / global git
configuration.
Alternatives Considered
1. Repo-level .gitignore / .gitattributes:
- Requires potentially frequent updates whenever the project's
underlying format is changed (new ignored folder or binary extension
added).
- While less likely - users can still commit root .gitignore changes
together with other project data yet-to-be-ignored - which makes the
problem rarer, but not solved.
- No way to limit settings to specific folders in general, unless
users themselves enforce some naming convention - effect will be
global (see zero assumption point above).
2. Shipped git hooks:
- Requires per-repo setup.
- Not all teams employ git hooks in their workflows - forcing their
usage is likely more overhead than just setting a single option.
- For more advanced git workflows users may already have custom hooks,
and git does not have a concept of hook wrappers / chaining - this
makes it quite hard to provide a self-contained solution provided by
the Software in question.
Additional Motivation
- As mentioned above, such an approach is employed by other widely
accepted tools, such as pre-commit.
- Other similar Git safety settings exist, like
[receive.denyCurrentBranch](https://git-scm.com/docs/git-config#Documentation/git-config.txt-receivedenyCurrentBranch).
- GitHub’s [.gitignore templates
repo](https://github.com/github/gitignore) demonstrates the ubiquity
of project-level ignore files, some of which could definitely benefit
from the current approach, making their effect more local &
manageable.
Contribution

If there is a consensus on the feature and the concept is accepted by the community - I am willing to contribute an implementation as the next step.

Thank you for considering this proposal - I am looking forward to hearing from you! Best regards, Kirill Sploshnov (GitHub: NormanXpp)

Torsten Bögershausen· Jul 25, 2025, 16:36 UTC · re: Kirill Sploshnov · lore

Re: Subject: [RFC] Add config option to enforce committing .gitignore / .gitattributes before other files

On Fri, Jul 25, 2025 at 12:40:30PM +0200, Kirill Sploshnov wrote:
Show 26 quoted lines
> Hi Git community,
> 
> I’d like to propose a new optional safety feature in Git related to
> .gitignore and .gitattributes handling.
> 
> [Problem Statement]
> 
> Some software ecosystems - such as game development tools (Unity,
> Unreal Engine) and other project-based environments - rely on
> predefined project folders that include .gitignore and .gitattributes.
> These files:
> 
> - Exclude large generated files, build caches, and temporary data.
> - Configure Git LFS for specific binary asset types.
> 
> To minimize interference with the rest of a repository, these files
> are often shipped inside each project folder, not at the repo root.
> This allows multiple projects or heterogeneous formats to coexist.
> 
> However, Git only applies ignore and attribute rules after these files
> are staged or committed. In practice, many users copy a project into
> an existing repo and immediately run:
> 
> > git add .
> 
> This stages everything - including an arbitrarily large cache or

Thanks for the detailed description. However, I am unable to reproduce it here. As an example, I ran this code: tb@mac:~> cd /tmp tb@mac:/tmp> mkdir 250725-gitignore tb@mac:/tmp> cd 250725-gitignore tb@mac:/tmp/250725-gitignore> git init Initialized empty Git repository in /tmp/250725-gitignore/.git/ tb@mac:/tmp/250725-gitignore> echo *.bak >.gitignore tb@mac:/tmp/250725-gitignore> touch a.bak tb@mac:/tmp/250725-gitignore> git add . tb@mac:/tmp/250725-gitignore> git status On branch master

No commits yet
Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   .gitignore

=========================== Your description indicates some problems. Are you able to demonstrate these with a shell-script ? The next step could be to find somebody to do the changes, and sends them, together with a/the test script, to this list.

However, there may be other solutions. Since you ask for a new config option: This needs to be applied to each and every workstation in use. How could this be done ? And if it is done from a central IT department, the there may be a way to configure git hooks on the work station.

Another way may be to configure the git server to refuse these kind of commits being pushed by running a ci-script. Not to talk about the chance to educate users of a tool to do it in a better way. Having said all this, there may be other suggestions, but first we need to understand the technical problems (that can be solved by a tool).

Show 103 quoted lines
> binaries that should have been excluded or redirected to LFS. This
> causes:
> 
> - Bloated history and additional cleanup.
> - LFS pointer issues and git workflow disruptions ("encountered files
> that should've pointers but weren't" errors for other repo users).
> 
> This problem is especially common when:
> 
> - Teams copy/import projects frequently.
> - Team members include non-engineering roles (artists, designers).
> - Tight schedules or manipulation of large amounts of small projects
> daily make careful staging problematic.
> 
> [Proposed Solution]
> 
> Introduce an optional config that requires .gitignore and
> .gitattributes to be committed before other files:
> 
> > [commit]
> >     requireIgnoreFirst = true
> 
> [Behaviour]
> 
> - If the option is set to true and ANY .gitignore or .gitattributes
> differ from HEAD (newly added or has changes) and other files are
> staged in the same commit THEN the commit fails.
> - Enforcement happens at git commit (not git add) to minimize disruption.
> - Error message includes a ready-to-use fix:
> 
> > Error: .gitignore and / or .gitattributes changes detected and must be committed before committing other files. Please commit them separately first, before adding other changes:
> > git reset && git add <path to .gitignore> && git add <path to .gitattributes> && git commit -m <commit message>
> 
> The idea is motivated by the [pre-commit](https://pre-commit.com/),
> the de-facto standard extension to use for git hooks managements - it
> behaves similarly, forbidding to commit anything if
> .pre-commit-config.yaml has any changes, requiring it to be committed
> first to avoid inconsistencies.
> 
> P.S.: this option could potentially be extended to include not just
> predefined paths but a list of patterns in a [.gitignore pattern
> format](https://git-scm.com/docs/gitignore#_pattern_format), but I see
> little incentive to have this customizable as of now - can be
> discussed, but the simpler suggested option should be sufficient for
> all cases.
> 
> Benefits
> 
> - Prevents accidental commits of caches or binary artifacts.
> - Reduces Git LFS misconfiguration disruptions.
> - Minimal intrusion - one local config setting. May be set up globally
> for companies / users with many repos.
> - Easy to advocate as a solution for the given software product users.
> - Zero assumptions about any repo layout or user's local / global git
> configuration.
> 
> Alternatives Considered
> 
> 1. Repo-level .gitignore / .gitattributes:
> 
> - Requires potentially frequent updates whenever the project's
> underlying format is changed (new ignored folder or binary extension
> added).
> - While less likely - users can still commit root .gitignore changes
> together with other project data yet-to-be-ignored - which makes the
> problem rarer, but not solved.
> - No way to limit settings to specific folders in general, unless
> users themselves enforce some naming convention - effect will be
> global (see zero assumption point above).
> 
> 2. Shipped git hooks:
> 
> - Requires per-repo setup.
> - Not all teams employ git hooks in their workflows - forcing their
> usage is likely more overhead than just setting a single option.
> - For more advanced git workflows users may already have custom hooks,
> and git does not have a concept of hook wrappers / chaining - this
> makes it quite hard to provide a self-contained solution provided by
> the Software in question.
> 
> Additional Motivation
> 
> - As mentioned above, such an approach is employed by other widely
> accepted tools, such as pre-commit.
> - Other similar Git safety settings exist, like
> [receive.denyCurrentBranch](https://git-scm.com/docs/git-config#Documentation/git-config.txt-receivedenyCurrentBranch).
> - GitHub’s [.gitignore templates
> repo](https://github.com/github/gitignore) demonstrates the ubiquity
> of project-level ignore files, some of which could definitely benefit
> from the current approach, making their effect more local &
> manageable.
> 
> Contribution
> 
> If there is a consensus on the feature and the concept is accepted by
> the community - I am willing to contribute an implementation as the
> next step.
> 
> Thank you for considering this proposal - I am looking forward to
> hearing from you!
> Best regards,
> Kirill Sploshnov (GitHub: NormanXpp)
> 
Junio C Hamano· Jul 26, 2025, 00:03 UTC · re: Torsten Bögershausen · lore

Re: Subject: [RFC] Add config option to enforce committing .gitignore / .gitattributes before other files

Torsten Bögershausen <tboegi@web.de> writes:
> Since you ask for a new config option: This needs to be applied
> to each and every workstation in use. How could this be done ?
> And if it is done from a central IT department, the there
> may be a way to configure git hooks on the work station.

Unfortunately, I think it is way too naïve an approach to help you all that much to merely stop you from committing anything before you have a .gitignore file, because presence of .gitignore is no sign that you are maintaining a good set of exclusion rules.

Recently in one of my toy projects, where .txt files are build products (hence I have "*.txt" excluded), I started tracking one externally-provided tool that is used by the build procedure of the project, but the tool comes its own "*.txt" template files, which means "git add NewToolDirectory/" left out half the files that come with the tool and are essential for the correct operation of that tool. Disaster recovery and history rewriting ensued, but the damage fortunately was small, as I caught it fairly soon before piling many commits on top.

Instead, you would want to catch a case where "git add" used to add _new_ files with a rather wide pathspec (e.g., in my case, I named a single directory and meant to add all the "relevant" files to the project---the problem was that the definition of "relevant" is vastly different from the contents that were tracked in the project historically and what was in the new directory) and ended up ignoring many files that _would_ have matched the pathspec and somehow flag it as a potential problem to the user.

Thanks.

← back to recent threads