git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Subject: [RFC] Add config option to enforce committing .gitignore / .gitattributes before other files
@ 2025-07-25 10:40 Kirill Sploshnov
  2025-07-25 16:36 ` Torsten Bögershausen
  0 siblings, 1 reply; 3+ messages in thread
From: Kirill Sploshnov @ 2025-07-25 10:40 UTC (permalink / raw)
  To: git

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)

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Subject: [RFC] Add config option to enforce committing .gitignore / .gitattributes before other files
  2025-07-25 10:40 Subject: [RFC] Add config option to enforce committing .gitignore / .gitattributes before other files Kirill Sploshnov
@ 2025-07-25 16:36 ` Torsten Bögershausen
  2025-07-26  0:03   ` Junio C Hamano
  0 siblings, 1 reply; 3+ messages in thread
From: Torsten Bögershausen @ 2025-07-25 16:36 UTC (permalink / raw)
  To: Kirill Sploshnov; +Cc: git

On Fri, Jul 25, 2025 at 12:40:30PM +0200, Kirill Sploshnov wrote:
> 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).

> 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)
> 

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Subject: [RFC] Add config option to enforce committing .gitignore / .gitattributes before other files
  2025-07-25 16:36 ` Torsten Bögershausen
@ 2025-07-26  0:03   ` Junio C Hamano
  0 siblings, 0 replies; 3+ messages in thread
From: Junio C Hamano @ 2025-07-26  0:03 UTC (permalink / raw)
  To: Torsten Bögershausen; +Cc: Kirill Sploshnov, git

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.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2025-07-26  0:03 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-25 10:40 Subject: [RFC] Add config option to enforce committing .gitignore / .gitattributes before other files Kirill Sploshnov
2025-07-25 16:36 ` Torsten Bögershausen
2025-07-26  0:03   ` Junio C Hamano

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 NNTP newsgroup(s).