{"thread":{"id":"63847","subject":"Subject: [RFC] Add config option to enforce committing .gitignore / .gitattributes before other files","startedAt":"2025-07-25T10:40:41Z","lastAt":"2025-07-26T00:03:46Z","messageCount":3,"participants":["Kirill Sploshnov","Torsten Bögershausen","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"522735","messageId":"CAOUUZ_wzNC=D4ZLf9Qw0xhFP+3ycTcPinRSCQA7aOJsiXA_FUQ@mail.gmail.com","threadId":"63847","inReplyTo":null,"subject":"Subject: [RFC] Add config option to enforce committing .gitignore / .gitattributes before other files","fromName":"Kirill Sploshnov","fromEmail":"sploshnov1998@gmail.com","sentAt":"2025-07-25T10:40:30Z","receivedAt":"2025-07-25T10:40:41Z","isPatch":false,"sender":{"key":"sploshnov1998@gmail.com","avatar":null},"body":"Hi Git community,\n\nI’d like to propose a new optional safety feature in Git related to\n.gitignore and .gitattributes handling.\n\n[Problem Statement]\n\nSome software ecosystems - such as game development tools (Unity,\nUnreal Engine) and other project-based environments - rely on\npredefined project folders that include .gitignore and .gitattributes.\nThese files:\n\n- Exclude large generated files, build caches, and temporary data.\n- Configure Git LFS for specific binary asset types.\n\nTo minimize interference with the rest of a repository, these files\nare often shipped inside each project folder, not at the repo root.\nThis allows multiple projects or heterogeneous formats to coexist.\n\nHowever, Git only applies ignore and attribute rules after these files\nare staged or committed. In practice, many users copy a project into\nan existing repo and immediately run:\n\n> git add .\n\nThis stages everything - including an arbitrarily large cache or\nbinaries that should have been excluded or redirected to LFS. This\ncauses:\n\n- Bloated history and additional cleanup.\n- LFS pointer issues and git workflow disruptions (\"encountered files\nthat should've pointers but weren't\" errors for other repo users).\n\nThis problem is especially common when:\n\n- Teams copy/import projects frequently.\n- Team members include non-engineering roles (artists, designers).\n- Tight schedules or manipulation of large amounts of small projects\ndaily make careful staging problematic.\n\n[Proposed Solution]\n\nIntroduce an optional config that requires .gitignore and\n.gitattributes to be committed before other files:\n\n> [commit]\n>     requireIgnoreFirst = true\n\n[Behaviour]\n\n- If the option is set to true and ANY .gitignore or .gitattributes\ndiffer from HEAD (newly added or has changes) and other files are\nstaged in the same commit THEN the commit fails.\n- Enforcement happens at git commit (not git add) to minimize disruption.\n- Error message includes a ready-to-use fix:\n\n> Error: .gitignore and / or .gitattributes changes detected and must be committed before committing other files. Please commit them separately first, before adding other changes:\n> git reset && git add <path to .gitignore> && git add <path to .gitattributes> && git commit -m <commit message>\n\nThe idea is motivated by the [pre-commit](https://pre-commit.com/),\nthe de-facto standard extension to use for git hooks managements - it\nbehaves similarly, forbidding to commit anything if\n.pre-commit-config.yaml has any changes, requiring it to be committed\nfirst to avoid inconsistencies.\n\nP.S.: this option could potentially be extended to include not just\npredefined paths but a list of patterns in a [.gitignore pattern\nformat](https://git-scm.com/docs/gitignore#_pattern_format), but I see\nlittle incentive to have this customizable as of now - can be\ndiscussed, but the simpler suggested option should be sufficient for\nall cases.\n\nBenefits\n\n- Prevents accidental commits of caches or binary artifacts.\n- Reduces Git LFS misconfiguration disruptions.\n- Minimal intrusion - one local config setting. May be set up globally\nfor companies / users with many repos.\n- Easy to advocate as a solution for the given software product users.\n- Zero assumptions about any repo layout or user's local / global git\nconfiguration.\n\nAlternatives Considered\n\n1. Repo-level .gitignore / .gitattributes:\n\n- Requires potentially frequent updates whenever the project's\nunderlying format is changed (new ignored folder or binary extension\nadded).\n- While less likely - users can still commit root .gitignore changes\ntogether with other project data yet-to-be-ignored - which makes the\nproblem rarer, but not solved.\n- No way to limit settings to specific folders in general, unless\nusers themselves enforce some naming convention - effect will be\nglobal (see zero assumption point above).\n\n2. Shipped git hooks:\n\n- Requires per-repo setup.\n- Not all teams employ git hooks in their workflows - forcing their\nusage is likely more overhead than just setting a single option.\n- For more advanced git workflows users may already have custom hooks,\nand git does not have a concept of hook wrappers / chaining - this\nmakes it quite hard to provide a self-contained solution provided by\nthe Software in question.\n\nAdditional Motivation\n\n- As mentioned above, such an approach is employed by other widely\naccepted tools, such as pre-commit.\n- Other similar Git safety settings exist, like\n[receive.denyCurrentBranch](https://git-scm.com/docs/git-config#Documentation/git-config.txt-receivedenyCurrentBranch).\n- GitHub’s [.gitignore templates\nrepo](https://github.com/github/gitignore) demonstrates the ubiquity\nof project-level ignore files, some of which could definitely benefit\nfrom the current approach, making their effect more local &\nmanageable.\n\nContribution\n\nIf there is a consensus on the feature and the concept is accepted by\nthe community - I am willing to contribute an implementation as the\nnext step.\n\nThank you for considering this proposal - I am looking forward to\nhearing from you!\nBest regards,\nKirill Sploshnov (GitHub: NormanXpp)\n"},{"id":"522759","messageId":"20250725163650.GA5869@tb-raspi4","threadId":"63847","inReplyTo":"CAOUUZ_wzNC=D4ZLf9Qw0xhFP+3ycTcPinRSCQA7aOJsiXA_FUQ@mail.gmail.com","subject":"Re: Subject: [RFC] Add config option to enforce committing .gitignore / .gitattributes before other files","fromName":"Torsten Bögershausen","fromEmail":"tboegi@web.de","sentAt":"2025-07-25T16:36:50Z","receivedAt":"2025-07-25T16:36:59Z","isPatch":false,"sender":{"key":"tboegi@web.de","avatar":"https://avatars.githubusercontent.com/u/7138363?v=4"},"body":"On Fri, Jul 25, 2025 at 12:40:30PM +0200, Kirill Sploshnov wrote:\n> Hi Git community,\n> \n> I’d like to propose a new optional safety feature in Git related to\n> .gitignore and .gitattributes handling.\n> \n> [Problem Statement]\n> \n> Some software ecosystems - such as game development tools (Unity,\n> Unreal Engine) and other project-based environments - rely on\n> predefined project folders that include .gitignore and .gitattributes.\n> These files:\n> \n> - Exclude large generated files, build caches, and temporary data.\n> - Configure Git LFS for specific binary asset types.\n> \n> To minimize interference with the rest of a repository, these files\n> are often shipped inside each project folder, not at the repo root.\n> This allows multiple projects or heterogeneous formats to coexist.\n> \n> However, Git only applies ignore and attribute rules after these files\n> are staged or committed. In practice, many users copy a project into\n> an existing repo and immediately run:\n> \n> > git add .\n> \n> This stages everything - including an arbitrarily large cache or\n\nThanks for the detailed description.\nHowever, I am unable to reproduce it here.\nAs an example, I ran this code:\ntb@mac:~> cd /tmp\ntb@mac:/tmp> mkdir 250725-gitignore\ntb@mac:/tmp> cd  250725-gitignore\ntb@mac:/tmp/250725-gitignore> git init\nInitialized empty Git repository in /tmp/250725-gitignore/.git/\ntb@mac:/tmp/250725-gitignore> echo *.bak >.gitignore\ntb@mac:/tmp/250725-gitignore> touch a.bak\ntb@mac:/tmp/250725-gitignore> git add .\ntb@mac:/tmp/250725-gitignore> git status\nOn branch master\n\nNo commits yet\n\nChanges to be committed:\n  (use \"git rm --cached <file>...\" to unstage)\n        new file:   .gitignore\n\n===========================\nYour description indicates some problems.\nAre you able to demonstrate these with a shell-script ?\nThe next step could be to find somebody to do the changes,\nand sends them, together with a/the test script, to this list.\n\nHowever, there may be other solutions.\nSince you ask for a new config option: This needs to be applied\nto each and every workstation in use. How could this be done ?\nAnd if it is done from a central IT department, the there\nmay be a way to configure git hooks on the work station.\n\nAnother way may be to configure the git server to refuse these\nkind of commits being pushed by running a ci-script.\nNot to talk about the chance to educate users of a tool\nto do it in a better way.\nHaving said all this, there may be other suggestions,\nbut first we need to understand the technical problems (that can be\nsolved by a tool).\n\n> binaries that should have been excluded or redirected to LFS. This\n> causes:\n> \n> - Bloated history and additional cleanup.\n> - LFS pointer issues and git workflow disruptions (\"encountered files\n> that should've pointers but weren't\" errors for other repo users).\n> \n> This problem is especially common when:\n> \n> - Teams copy/import projects frequently.\n> - Team members include non-engineering roles (artists, designers).\n> - Tight schedules or manipulation of large amounts of small projects\n> daily make careful staging problematic.\n> \n> [Proposed Solution]\n> \n> Introduce an optional config that requires .gitignore and\n> .gitattributes to be committed before other files:\n> \n> > [commit]\n> >     requireIgnoreFirst = true\n> \n> [Behaviour]\n> \n> - If the option is set to true and ANY .gitignore or .gitattributes\n> differ from HEAD (newly added or has changes) and other files are\n> staged in the same commit THEN the commit fails.\n> - Enforcement happens at git commit (not git add) to minimize disruption.\n> - Error message includes a ready-to-use fix:\n> \n> > Error: .gitignore and / or .gitattributes changes detected and must be committed before committing other files. Please commit them separately first, before adding other changes:\n> > git reset && git add <path to .gitignore> && git add <path to .gitattributes> && git commit -m <commit message>\n> \n> The idea is motivated by the [pre-commit](https://pre-commit.com/),\n> the de-facto standard extension to use for git hooks managements - it\n> behaves similarly, forbidding to commit anything if\n> .pre-commit-config.yaml has any changes, requiring it to be committed\n> first to avoid inconsistencies.\n> \n> P.S.: this option could potentially be extended to include not just\n> predefined paths but a list of patterns in a [.gitignore pattern\n> format](https://git-scm.com/docs/gitignore#_pattern_format), but I see\n> little incentive to have this customizable as of now - can be\n> discussed, but the simpler suggested option should be sufficient for\n> all cases.\n> \n> Benefits\n> \n> - Prevents accidental commits of caches or binary artifacts.\n> - Reduces Git LFS misconfiguration disruptions.\n> - Minimal intrusion - one local config setting. May be set up globally\n> for companies / users with many repos.\n> - Easy to advocate as a solution for the given software product users.\n> - Zero assumptions about any repo layout or user's local / global git\n> configuration.\n> \n> Alternatives Considered\n> \n> 1. Repo-level .gitignore / .gitattributes:\n> \n> - Requires potentially frequent updates whenever the project's\n> underlying format is changed (new ignored folder or binary extension\n> added).\n> - While less likely - users can still commit root .gitignore changes\n> together with other project data yet-to-be-ignored - which makes the\n> problem rarer, but not solved.\n> - No way to limit settings to specific folders in general, unless\n> users themselves enforce some naming convention - effect will be\n> global (see zero assumption point above).\n> \n> 2. Shipped git hooks:\n> \n> - Requires per-repo setup.\n> - Not all teams employ git hooks in their workflows - forcing their\n> usage is likely more overhead than just setting a single option.\n> - For more advanced git workflows users may already have custom hooks,\n> and git does not have a concept of hook wrappers / chaining - this\n> makes it quite hard to provide a self-contained solution provided by\n> the Software in question.\n> \n> Additional Motivation\n> \n> - As mentioned above, such an approach is employed by other widely\n> accepted tools, such as pre-commit.\n> - Other similar Git safety settings exist, like\n> [receive.denyCurrentBranch](https://git-scm.com/docs/git-config#Documentation/git-config.txt-receivedenyCurrentBranch).\n> - GitHub’s [.gitignore templates\n> repo](https://github.com/github/gitignore) demonstrates the ubiquity\n> of project-level ignore files, some of which could definitely benefit\n> from the current approach, making their effect more local &\n> manageable.\n> \n> Contribution\n> \n> If there is a consensus on the feature and the concept is accepted by\n> the community - I am willing to contribute an implementation as the\n> next step.\n> \n> Thank you for considering this proposal - I am looking forward to\n> hearing from you!\n> Best regards,\n> Kirill Sploshnov (GitHub: NormanXpp)\n> \n"},{"id":"522779","messageId":"xmqqa54r3jj3.fsf@gitster.g","threadId":"63847","inReplyTo":"20250725163650.GA5869@tb-raspi4","subject":"Re: Subject: [RFC] Add config option to enforce committing .gitignore / .gitattributes before other files","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-07-26T00:03:44Z","receivedAt":"2025-07-26T00:03:46Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Torsten Bögershausen <tboegi@web.de> writes:\n\n> Since you ask for a new config option: This needs to be applied\n> to each and every workstation in use. How could this be done ?\n> And if it is done from a central IT department, the there\n> may be a way to configure git hooks on the work station.\n\n\nUnfortunately, I think it is way too naïve an approach to help you\nall that much to merely stop you from committing anything before you\nhave a .gitignore file, because presence of .gitignore is no sign\nthat you are maintaining a good set of exclusion rules.\n\nRecently in one of my toy projects, where .txt files are build\nproducts (hence I have \"*.txt\" excluded), I started tracking one\nexternally-provided tool that is used by the build procedure of the\nproject, but the tool comes its own \"*.txt\" template files, which\nmeans \"git add NewToolDirectory/\" left out half the files that come\nwith the tool and are essential for the correct operation of that\ntool.  Disaster recovery and history rewriting ensued, but the\ndamage fortunately was small, as I caught it fairly soon before\npiling many commits on top.\n\nInstead, you would want to catch a case where \"git add\" used to add\n_new_ files with a rather wide pathspec (e.g., in my case, I named a\nsingle directory and meant to add all the \"relevant\" files to the\nproject---the problem was that the definition of \"relevant\" is\nvastly different from the contents that were tracked in the project\nhistorically and what was in the new directory) and ended up\nignoring many files that _would_ have matched the pathspec and\nsomehow flag it as a potential problem to the user.\n\nThanks.\n"}]}