{"thread":{"id":"59898","subject":"Bug: git add does not process gitignore properly","startedAt":"2023-06-22T19:38:26Z","lastAt":"2023-06-24T22:20:23Z","messageCount":4,"participants":["David C Black","Eric Sunshine","Phillip Wood","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"478695","messageId":"CWLP265MB3841D32521E79202079DB7F58C22A@CWLP265MB3841.GBRP265.PROD.OUTLOOK.COM","threadId":"59898","inReplyTo":null,"subject":"Bug: git add does not process gitignore properly","fromName":"David C Black","fromEmail":"david.black@doulos.com","sentAt":"2023-06-22T19:38:19Z","receivedAt":"2023-06-22T19:38:26Z","isPatch":false,"sender":{"key":"david.black@doulos.com","avatar":null},"body":"Thank you for filling out a Git bug report!\nPlease answer the following questions to help us understand your issue.\n \nWhat did you do before the bug happened?\n \nSitting at the rood of my working directory I attempted to add a file to the git repository with:\n \n> git add extern/bin/build\n \nThe repository had the following .gitignore file contents:\n \n> /extern/\n> !/extern/bin/\n> !/extern/ABOUT.md\n \nWhat did you expect to happen? (Expected behavior)\n \nI expected it to be added.\n \nWhat happened instead? (Actual behavior)\n \nI received an error message:\n \n> The following paths are ignored by one of your .gitignore files:\n> extern\n> hint: Use -f if you really want to add them.\n> hint: Turn this message off by running\n> hint: \"git config advice.addIgnoredFile false\"\n \nWhat's different between what you expected and what actually happened?\n \nBy negating entries in the /extern/bin/ directory, I did not expect an error\nmessage. Of course adding -f made it work, but I think it does not match the\ndescribed behavior for this tool.\n \nAnything else you want to add:\n \nPlease review the rest of the bug report below.\nYou can delete any lines you don't wish to share.\n \n[System Info]\ngit version:\ngit version 2.41.0\ncpu: arm64\nno commit associated with this build\nsizeof-long: 8\nsizeof-size_t: 8\nshell-path: /bin/sh\nfeature: fsmonitor--daemon\nuname: Darwin 22.5.0 Darwin Kernel Version 22.5.0: Mon Apr 24 20:52:24 PDT 2023; root:xnu-8796.121.2~5/RELEASE_ARM64_T6000 arm64\ncompiler info: clang: 14.0.3 (clang-1403.0.22.14.1)\nlibc info: no libc information available\n$SHELL (typically, interactive shell): /bin/zsh\n \n \n[Enabled Hooks]\n \n-- \nDavid C. Black, Electronics/Programming Technology Instructor\n"},{"id":"478754","messageId":"CAPig+cQ1qzO5txhZhki4UrvLBThdgo-aknBmEkNSjFhR9WXLRg@mail.gmail.com","threadId":"59898","inReplyTo":"CWLP265MB3841D32521E79202079DB7F58C22A@CWLP265MB3841.GBRP265.PROD.OUTLOOK.COM","subject":"Re: Bug: git add does not process gitignore properly","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2023-06-23T22:07:22Z","receivedAt":"2023-06-23T22:07:50Z","isPatch":false,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Thu, Jun 22, 2023 at 3:56 PM David C Black <david.black@doulos.com> wrote:\n> Sitting at the rood of my working directory I attempted to add a file to the git repository with:\n> > git add extern/bin/build\n>\n> The repository had the following .gitignore file contents:\n> > /extern/\n> > !/extern/bin/\n> > !/extern/ABOUT.md\n>\n> I received an error message:\n> > The following paths are ignored by one of your .gitignore files:\n> > extern\n> > hint: Use -f if you really want to add them.\n>\n> By negating entries in the /extern/bin/ directory, I did not expect an error\n> message. Of course adding -f made it work, but I think it does not match the\n> described behavior for this tool.\n\nThis appears to be working as documented. From the gitginore(5) man page:\n\n    An optional prefix \"!\" which negates the pattern; any matching\n    file excluded by a previous pattern will become included again. It\n    is not possible to re-include a file if a parent directory of that\n    file is excluded.\n\nIn your .gitignore file, /extern/ is ignored, which means that the\nsubsequent \"!/extern/.../\" lines are ineffectual. So, as far as Git is\nconcerned, /extern/bin/build is indeed ignored, thus its refusal\nwithout --force.\n"},{"id":"478767","messageId":"d748b4bb-6be2-4936-04d0-f0edcf228dfb@gmail.com","threadId":"59898","inReplyTo":"CAPig+cQ1qzO5txhZhki4UrvLBThdgo-aknBmEkNSjFhR9WXLRg@mail.gmail.com","subject":"Re: Bug: git add does not process gitignore properly","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2023-06-24T10:13:22Z","receivedAt":"2023-06-24T10:13:33Z","isPatch":false,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 23/06/2023 23:07, Eric Sunshine wrote:\n> On Thu, Jun 22, 2023 at 3:56 PM David C Black <david.black@doulos.com> wrote:\n>> Sitting at the rood of my working directory I attempted to add a file to the git repository with:\n>>> git add extern/bin/build\n>>\n>> The repository had the following .gitignore file contents:\n>>> /extern/\n>>> !/extern/bin/\n>>> !/extern/ABOUT.md\n>>\n>> I received an error message:\n>>> The following paths are ignored by one of your .gitignore files:\n>>> extern\n>>> hint: Use -f if you really want to add them.\n>>\n>> By negating entries in the /extern/bin/ directory, I did not expect an error\n>> message. Of course adding -f made it work, but I think it does not match the\n>> described behavior for this tool.\n> \n> This appears to be working as documented. From the gitginore(5) man page:\n> \n>      An optional prefix \"!\" which negates the pattern; any matching\n>      file excluded by a previous pattern will become included again. It\n>      is not possible to re-include a file if a parent directory of that\n>      file is excluded.\n> \n> In your .gitignore file, /extern/ is ignored, which means that the\n> subsequent \"!/extern/.../\" lines are ineffectual. So, as far as Git is\n> concerned, /extern/bin/build is indeed ignored, thus its refusal\n> without --force.\n\nI think the usual way around this is to use patterns like\n\n\t/extern/*\n\t!/extern/bin/\n\t!/extern/ABOUT.md\n\nsee the example on the gitignore man page.\n\nBest Wishes\n\nPhillip\n"},{"id":"478776","messageId":"xmqqjzvs7bbr.fsf@gitster.g","threadId":"59898","inReplyTo":"d748b4bb-6be2-4936-04d0-f0edcf228dfb@gmail.com","subject":"Re: Bug: git add does not process gitignore properly","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-06-24T22:19:20Z","receivedAt":"2023-06-24T22:20:23Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood123@gmail.com> writes:\n\n> I think the usual way around this is to use patterns like\n>\n> \t/extern/*\n> \t!/extern/bin/\n> \t!/extern/ABOUT.md\n>\n> see the example on the gitignore man page.\n\nThanks for a very good suggestion.\n\nThe behaviour may be somewhat counter-intuitive, especially when you\nhave \"/extern/\" followed by \"!/extern/blah\" in the same file.  The\noriginal rationale for this was because the behaviour becomes\nconsistent between the cases where\n\n (1) these two patterns appear in the same top-level .gitignore\n     file, and\n\n (2) \"/extern/\" is in the top-level .gitignore file and \"!/bin/\" is\n     in \".gitignore\" file in the \"extern/\" directory\n\nwhich ought to be the moral equivalents.\n\nThere have been at least two attempts to change this, but without\nmuch success.\n\n - 57534ee7 (dir.c: don't exclude whole dir prematurely if neg\n   pattern may match, 2015-09-21) tried but it caused breakages\n   reported on the list [*1*, *2*] and got reverted at 8c722360\n   (Revert \"dir.c: don't exclude whole dir prematurely if neg\n   pattern may match\", 2016-01-08).\n\n - 5e57f9c3 (Merge branch 'nd/exclusion-regression-fix', 2016-02-24)\n   was a merge of another attempt, which again had to be reverted at\n   5cee3493 (Revert \"Merge branch 'nd/exclusion-regression-fix'\",\n   2016-03-18).\n\nIt is dubious if it is worth making another attempt to change it.\n\"Fixing\" this and still keeping consistency between the two ways to\nspell the same pair of rules would mean that even \"/extern/\" in the\n\".gitignore\" file in a higher level tells us not to bother with the\n\"extern\" directory, we would have to look for \"extern/.gitignore\"\njust in case it unignores something, which would probably make it\nunacceptably costly.  It would be quite a backward incompatible\nchange, too.\n\n\n[References]\n*1* Git 2.7.0 gitignore behaviour regression:\nhttps://lore.kernel.org/git/20160107234455.GB265296@vauxhall.crustytoothpaste.net/\n\n*2* Behavior change in 2.7.0: With core.sparseCheckout some files have\n    the skip-worktree bit set after a checkout.:\nhttps://lore.kernel.org/git/trinity-5caa2985-5cf1-453b-9a9e-bcce057f8615-1452249323061@3capp-gmx-bs51/\n"}]}