{"thread":{"id":"65910","subject":"Unexpected recursion in 'git rm'","startedAt":"2026-07-02T07:49:14Z","lastAt":"2026-07-03T20:41:22Z","messageCount":8,"participants":["Евгений Плискин","Matt Hunter","Patrick Steinhardt","Phillip Wood","Mikael Magnusson","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"546958","messageId":"323134122.20260702104910@gmail.com","threadId":"65910","inReplyTo":null,"subject":"Unexpected recursion in 'git rm'","fromName":"Евгений Плискин","fromEmail":"eugene.pliskin@gmail.com","sentAt":"2026-07-02T07:49:10Z","receivedAt":"2026-07-02T07:49:14Z","isPatch":false,"body":"Hello.\n\nThe following git command does recurse directories as contrary to the reference (https://git-scm.com/docs/git-rm):\n\n    git rm -n *.json\n\nWithout directory specification before '*.json' this command is not expected to recurse directories, but it really does.\n\ngit version 2.55.0.windows.1\n\n-- \nRegards,\nEugene Pliskin                          mailto:eugene.pliskin@gmail.com\n\n"},{"id":"547043","messageId":"DJOQR6XMG7QZ.2UH68XH0N1D7W@lfurio.us","threadId":"65910","inReplyTo":"323134122.20260702104910@gmail.com","subject":"Re: Unexpected recursion in 'git rm'","fromName":"Matt Hunter","fromEmail":"m@lfurio.us","sentAt":"2026-07-03T07:01:19Z","receivedAt":"2026-07-03T07:01:20Z","isPatch":false,"body":"On Thu Jul 2, 2026 at 3:49 AM EDT, Евгений Плискин wrote:\n> Hello.\n>\n> The following git command does recurse directories as contrary to the reference (https://git-scm.com/docs/git-rm):\n>\n>     git rm -n *.json\n>\n> Without directory specification before '*.json' this command is not expected to recurse directories, but it really does.\n>\n> git version 2.55.0.windows.1\n\nHi - I threw a quick test repo together, but did not see the result you\ndescribe.  Could you produce a script or series of commands to reproduce\nthe problem?\n"},{"id":"547046","messageId":"akdzSHrJ4DfdUWoS@pks.im","threadId":"65910","inReplyTo":"323134122.20260702104910@gmail.com","subject":"Re: Unexpected recursion in 'git rm'","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-07-03T08:31:04Z","receivedAt":"2026-07-03T08:31:09Z","isPatch":false,"body":"Hi,\n\nOn Thu, Jul 02, 2026 at 10:49:10AM +0300, Евгений Плискин wrote:\n> Hello.\n> \n> The following git command does recurse directories as contrary to the\n> reference (https://git-scm.com/docs/git-rm):\n> \n>     git rm -n *.json\n> \n> Without directory specification before '*.json' this command is not\n> expected to recurse directories, but it really does.\n\nThis is expected behaviour, as the argument to git-rm(1) is a pathspec,\nand \"*\" matches directory separators by default, see also gitglossary(7)\nunder \"pathspec\":\n\n  • the pathspec up to the last slash represents a directory prefix. The\n    scope of that pathspec is limited to that subtree.\n\n  • the rest of the pathspec is a pattern for the remainder of the\n    pathname. Paths relative to the directory prefix will be matched\n    against that pattern using fnmatch(3); in particular, * and ? can\n    match directory separators.\n\n  For example, Documentation/*.jpg will match all .jpg files in the\n  Documentation subtree, including Documentation/chapter_1/figure_1.jpg.\n\nCould you maybe clarify which part of git-rm(1) made you think that this\nwouldn't happen?\n\nThanks!\n\nPatrick\n"},{"id":"547064","messageId":"5827a94f-0f13-4747-8257-b67fb9d79ecd@gmail.com","threadId":"65910","inReplyTo":"akdzSHrJ4DfdUWoS@pks.im","subject":"Re: Unexpected recursion in 'git rm'","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2026-07-03T10:04:58Z","receivedAt":"2026-07-03T10:05:01Z","isPatch":false,"body":"On 03/07/2026 09:31, Patrick Steinhardt wrote:\n> On Thu, Jul 02, 2026 at 10:49:10AM +0300, Евгений Плискин wrote:\n>> Hello.\n>>\n>> The following git command does recurse directories as contrary to the\n>> reference (https://git-scm.com/docs/git-rm):\n>>\n>>      git rm -n *.json\n>>\n>> Without directory specification before '*.json' this command is not\n>> expected to recurse directories, but it really does.\n\nAre there any \".json\" files in the directory where you're running this? \nAs the glob is not quoted, I think maybe what is happening is that there \nare no matching files in the current directory so the shell is not \nexpanding the glob as you expect and is passing it to git which treats \nit as Patrick explains below.\n\nThanks\n\nPhillip\n\n> This is expected behaviour, as the argument to git-rm(1) is a pathspec,\n> and \"*\" matches directory separators by default, see also gitglossary(7)\n> under \"pathspec\":\n> \n>    • the pathspec up to the last slash represents a directory prefix. The\n>      scope of that pathspec is limited to that subtree.\n> \n>    • the rest of the pathspec is a pattern for the remainder of the\n>      pathname. Paths relative to the directory prefix will be matched\n>      against that pattern using fnmatch(3); in particular, * and ? can\n>      match directory separators.\n> \n>    For example, Documentation/*.jpg will match all .jpg files in the\n>    Documentation subtree, including Documentation/chapter_1/figure_1.jpg.\n> \n> Could you maybe clarify which part of git-rm(1) made you think that this\n> wouldn't happen?\n> \n> Thanks!\n> \n> Patrick\n> \n\n"},{"id":"547078","messageId":"aketk4ensXGZS4eI@pks.im","threadId":"65910","inReplyTo":"1756071445.20260703123414@gmail.com","subject":"Re: Unexpected recursion in 'git rm'","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-07-03T12:39:47Z","receivedAt":"2026-07-03T12:39:52Z","isPatch":false,"body":"Adding the mailing list back into Cc.\n\nOn Fri, Jul 03, 2026 at 12:34:14PM +0300, Евгений Плискин wrote:\n> > This is expected behaviour, as the argument to git-rm(1) is a pathspec, and \"*\" matches directory separators by default, see also gitglossary(7) under \"pathspec\":\n> >   • the pathspec up to the last slash represents a directory prefix. The  scope of that pathspec is limited to that subtree.\n> >   • the rest of the pathspec is a pattern for the remainder of the pathname. Paths relative to the directory prefix will be matched against that pattern using fnmatch(3); in particular, * and ? can match directory separators.\n> >   For example, Documentation/*.jpg will match all .jpg files in the  Documentation subtree, including Documentation/chapter_1/figure_1.jpg.\n> > Could you maybe clarify which part of git-rm(1) made you think that this wouldn't happen?\n> \n> Thank you for your reply. I believe you are correct.\n> \n> I have made more research and found a way to remove files in current directory only without recursion into subdirectories:\n>      git rm -n ':(glob)*.json'\n\nYup, that wouldn't cross directory separators indeed.\n\nPatrick\n"},{"id":"547092","messageId":"DJOYGY682OLT.1TPZHGTA5EMQQ@lfurio.us","threadId":"65910","inReplyTo":"1978773121.20260703123754@gmail.com","subject":"Re: Unexpected recursion in 'git rm'","fromName":"Matt Hunter","fromEmail":"m@lfurio.us","sentAt":"2026-07-03T13:04:05Z","receivedAt":"2026-07-03T13:04:06Z","isPatch":false,"body":"On Fri Jul 3, 2026 at 5:37 AM EDT, Евгений Плискин wrote:\n>> Hi - I threw a quick test repo together, but did not see the result you describe.  Could you produce a script or series of commands to reproduce the problem?\n> Hi. Thank you for your reply. \n> I was advised meantime that indeed this behaviour is expected:\n>\n> This is expected behaviour, as the argument to git-rm(1) is a pathspec,\n> and \"*\" matches directory separators by default, see also gitglossary(7)\n> under \"pathspec\":\n\nYup, I see that now, and that was the difference maker in my test.  I\nhad json files in the directory I was working, as well as at nested\npaths.  My (non-windows) shell globbed to pass just the upper files.\n\nTo address Patrick's question in <akdzSHrJ4DfdUWoS@pks.im>:\n\n> Could you maybe clarify which part of git-rm(1) made you think that this\n> wouldn't happen?\n\nI'll say that I _don't_ think the man page is unclear in this regard\n(having given it a look just now).  To me, this is just one of the\naspects of git that is integrated with its unix counterpart well enough\n(git-rm vs. rm) that you can forget the finer details like this fairly\neasily.\n\nAnd since the command is so straightforward, I couldn't tell you the\nlast time I pulled up git-rm(1) as a reference.\n"},{"id":"547102","messageId":"CAHYJk3RXY5-YgcYWY2y8vOcHG5Frf91ehNiZRr66sJJH5F=qLQ@mail.gmail.com","threadId":"65910","inReplyTo":"323134122.20260702104910@gmail.com","subject":"Re: Unexpected recursion in 'git rm'","fromName":"Mikael Magnusson","fromEmail":"mikachu@gmail.com","sentAt":"2026-07-03T15:25:52Z","receivedAt":"2026-07-03T15:26:09Z","isPatch":false,"body":"On Thu, Jul 2, 2026 at 9:51 AM Евгений Плискин <eugene.pliskin@gmail.com> wrote:\n>\n> Hello.\n>\n> The following git command does recurse directories as contrary to the reference (https://git-scm.com/docs/git-rm):\n>\n>     git rm -n *.json\n>\n> Without directory specification before '*.json' this command is not expected to recurse directories, but it really does.\n>\n> git version 2.55.0.windows.1\n\nI can't see any formulation in the manpage reference that suggests it\nwouldn't recurse, though you might overall get less surprised if you\nset the failglob option in bash. Then the shell would notice *.json\nhas no matches, and you'd have to say git rm -n '*.json' to let git\nprocess the glob instead of the shell. See also\nhttps://git-scm.com/docs/gitglossary (as referenced from the git-rm\npage) which says:\n\n  the rest of the pathspec is a pattern for the remainder of the pathname.\n  Paths relative to the directory prefix will be matched against that\n  pattern using fnmatch(3); in particular, * and ? can match directory\n  separators.\n\n-- \nMikael Magnusson\n"},{"id":"547120","messageId":"xmqqo6gnhkls.fsf@gitster.g","threadId":"65910","inReplyTo":"CAHYJk3RXY5-YgcYWY2y8vOcHG5Frf91ehNiZRr66sJJH5F=qLQ@mail.gmail.com","subject":"Re: Unexpected recursion in 'git rm'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-07-03T20:41:19Z","receivedAt":"2026-07-03T20:41:22Z","isPatch":false,"body":"Mikael Magnusson <mikachu@gmail.com> writes:\n\n> ..., though you might overall get less surprised if you\n> set the failglob option in bash.\n\nExcellent suggestion.\n"}]}