threads / bug / 55551

[BUG] ** glob pattern in git diff doesn't match root directory

Subject: [BUG] ** glob pattern in git diff doesn't match root directory

## tl;dr

7 messages between Apr 24, 2021 and Apr 27, 2021.

replies: 6people: 3as markdown or json

Shoaib Meenai· Apr 24, 2021, 02:52 UTC · lore
Hi all,

When I use a `**/` glob pattern with `git diff`, it doesn't seem to match in the root directory. The documentation for gitgnore says that a leading `**/` should match in all directories, and I would expect it to behave the same way for `git diff`. For example:

$ git --version git version 2.31.1.527.g47e6f16901 # built from the `next` branch $ mkdir /tmp/globtest && cd /tmp/globtest $ git init $ echo foo > foo $ mkdir sub $ echo subfoo > sub/foo $ git add . $ git commit -m 'Initial commit' $ echo bar > foo $ echo subbar > sub/foo $ git --no-pager diff '**/foo'

diff --git a/sub/foo b/sub/foo
index ef7889f..2b2ab6c 100644
--- a/sub/foo
+++ b/sub/foo
@@ -1 +1 @@
-subfoo
+subbar

Only the diff to `sub/foo` is printed, whereas I'd expect the change to
the top-level `foo` to be printed as well. `git diff '**foo'` does behave
as I would expect. This also happens with a `**` in the middle of a
pattern; e.g., `sub/**/bar` will match `sub/dir/bar` but not `sub/bar`.

Am I misunderstanding how `**` should work, or is this a bug?

Thanks,
Shoaib
Felipe Contreras· Apr 24, 2021, 03:31 UTC · re: Shoaib Meenai · lore

RE: [BUG] ** glob pattern in git diff doesn't match root directory

Shoaib Meenai wrote:
> Am I misunderstanding how `**` should work, or is this a bug?
I would say this is a bug, but I'm not familiar with pathspecs.

I stumbled upoon a very similar issue (I wanted to find all the *.jpg in the repository). I couldn't find another way to do it but:

  git diff ':(glob)**/foo'
Cheers.
-- 
Felipe Contreras
=?utf-8?B?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason· Apr 26, 2021, 08:23 UTC · re: Felipe Contreras · lore

Re: [BUG] ** glob pattern in git diff doesn't match root directory

On Sat, Apr 24 2021, Felipe Contreras wrote:
> Shoaib Meenai wrote:
>> Am I misunderstanding how `**` should work, or is this a bug?
>
> I would say this is a bug, but I'm not familiar with pathspecs.
I replied on the "is it a bug" upthread...
> I stumbled upoon a very similar issue (I wanted to find all the *.jpg in
> the repository). I couldn't find another way to do it but:
>
>   git diff ':(glob)**/foo'

Maybe I'm missing something, but if you want to find all *.jpg isn't that just:

    git diff '*.jpg'
?
Felipe Contreras· Apr 27, 2021, 19:58 UTC · re: =?utf-8?B?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason · lore

Re: [BUG] ** glob pattern in git diff doesn't match root directory

=?utf-8?B?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason wrote:
> On Sat, Apr 24 2021, Felipe Contreras wrote:
Show 11 quoted lines
> > I stumbled upoon a very similar issue (I wanted to find all the *.jpg in
> > the repository). I couldn't find another way to do it but:
> >
> >   git diff ':(glob)**/foo'
> 
> Maybe I'm missing something, but if you want to find all *.jpg isn't
> that just:
> 
>     git diff '*.jpg'
> 
> ?
Right, actually I misremembered; it was all '.gitignore' files.

If I do '*.gitignore' that matches all the files, but also any $x.gitignore files. If I want only '.gitignore' files I need ':(glob)**/.gitignore'.

Cheers.
-- 
Felipe Contreras
Shoaib Meenai· Apr 26, 2021, 20:45 UTC · re: Felipe Contreras · lore

Re: [BUG] ** glob pattern in git diff doesn't match root directory

Show 10 quoted lines
> On 4/23/21, 8:32 PM, "Felipe Contreras" <felipe.contreras@gmail.com> wrote:
> Shoaib Meenai wrote:
>> Am I misunderstanding how `**` should work, or is this a bug?
>
> I would say this is a bug, but I'm not familiar with pathspecs.
>
> I stumbled upoon a very similar issue (I wanted to find all the *.jpg in
> the repository). I couldn't find another way to do it but:
>
>   git diff ':(glob)**/foo'

Ah, "pathspec" is the piece of vocabulary that I was missing. Looking at the git documentation for pathspecs, I can see how this is supposed to behave, and `:(glob)` is exactly the behavior I'm looking for. Thank you!

Show 5 quoted lines
>
> Cheers.
>
> --
> Felipe Contreras
=?utf-8?B?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason· Apr 26, 2021, 08:23 UTC · re: Shoaib Meenai · lore

Re: [BUG] ** glob pattern in git diff doesn't match root directory

On Sat, Apr 24 2021, Shoaib Meenai wrote:
Show 33 quoted lines
> Hi all,
>
> When I use a `**/` glob pattern with `git diff`, it doesn't seem to
> match in the root directory. The documentation for gitgnore says that a
> leading `**/` should match in all directories, and I would expect it to
> behave the same way for `git diff`. For example:
>
> $ git --version
> git version 2.31.1.527.g47e6f16901 # built from the `next` branch
> $ mkdir /tmp/globtest && cd /tmp/globtest
> $ git init
> $ echo foo > foo
> $ mkdir sub
> $ echo subfoo > sub/foo
> $ git add .
> $ git commit -m 'Initial commit'
> $ echo bar > foo
> $ echo subbar > sub/foo
> $ git --no-pager diff '**/foo'
> diff --git a/sub/foo b/sub/foo
> index ef7889f..2b2ab6c 100644
> --- a/sub/foo
> +++ b/sub/foo
> @@ -1 +1 @@
> -subfoo
> +subbar
>
> Only the diff to `sub/foo` is printed, whereas I'd expect the change to
> the top-level `foo` to be printed as well. `git diff '**foo'` does behave
> as I would expect. This also happens with a `**` in the middle of a
> pattern; e.g., `sub/**/bar` will match `sub/dir/bar` but not `sub/bar`.
>
> Am I misunderstanding how `**` should work, or is this a bug?

It's not a bug in behavior, but reading the documentation I think it's buggy in describing how it works.

The behavior of ** here is to match anything, including a slash, but you yourself are providing the slash with "**/".

This behavior is different under :(glob) where we would match "foo" on the top-level.

See t/t3070-wildmatch.sh, is particular the "**/foo" test-case.

We adopted this code from rsync originally, I think its manual page is better at describing how it works, as an aside I see they've since added a "***" which we won't have, and maybe some other features.

Shoaib Meenai· Apr 26, 2021, 20:48 UTC · re: =?utf-8?B?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason · lore

Re: [BUG] ** glob pattern in git diff doesn't match root directory

Show 51 quoted lines
> On 4/26/21, 1:23 AM, "=?utf-8?B?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason" <avarab@gmail.com> wrote:
> On Sat, Apr 24 2021, Shoaib Meenai wrote:
>
>> Hi all,
>>
>> When I use a `**/` glob pattern with `git diff`, it doesn't seem to
>> match in the root directory. The documentation for gitgnore says that a
>> leading `**/` should match in all directories, and I would expect it to
>> behave the same way for `git diff`. For example:
>>
>> $ git --version
>> git version 2.31.1.527.g47e6f16901 # built from the `next` branch
>> $ mkdir /tmp/globtest && cd /tmp/globtest
>> $ git init
>> $ echo foo > foo
>> $ mkdir sub
>> $ echo subfoo > sub/foo
>> $ git add .
>> $ git commit -m 'Initial commit'
>> $ echo bar > foo
>> $ echo subbar > sub/foo
>> $ git --no-pager diff '**/foo'
>> diff --git a/sub/foo b/sub/foo
>> index ef7889f..2b2ab6c 100644
>> --- a/sub/foo
>> +++ b/sub/foo
>> @@ -1 +1 @@
>> -subfoo
>> +subbar
>>
>> Only the diff to `sub/foo` is printed, whereas I'd expect the change to
>> the top-level `foo` to be printed as well. `git diff '**foo'` does behave
>> as I would expect. This also happens with a `**` in the middle of a
>> pattern; e.g., `sub/**/bar` will match `sub/dir/bar` but not `sub/bar`.
>>
>> Am I misunderstanding how `**` should work, or is this a bug?
>
> It's not a bug in behavior, but reading the documentation I think it's
> buggy in describing how it works.
>
> The behavior of ** here is to match anything, including a slash, but you
> yourself are providing the slash with "**/".
>
> This behavior is different under :(glob) where we would match "foo" on
> the top-level.
>
> See t/t3070-wildmatch.sh, is particular the "**/foo" test-case.
>
> We adopted this code from rsync originally, I think its manual page is
> better at describing how it works, as an aside I see they've since added
> a "***" which we won't have, and maybe some other features.

Got it, thank you! I was providing a slash myself because my intention was to only match paths that are exactly "foo", whereas e.g. '**foo' would also match 'some_prefix_and_then_foo'. `:(glob)` does exactly what I want though; thank you.

← back to recent threads