Are leading asterisks “**/” redundant in .gitignore path matching syntax?

后端 未结 2 2000
再見小時候
再見小時候 2021-01-02 08:25

Are there any usages that can\'t be replaced by equivalents without asterisks?

Two consecutive asterisks (\"**\") in patterns matched against full
pathname m         


        
相关标签:
2条回答
  • 2021-01-02 08:44

    There was (but isn't any more, thanks to editing) a faulty assumption in the question. To demonstrate the issue:

    $ mkdir tignore
    $ cd tignore
    $ git init
    Initialized empty Git repository in .../tignore/.git
    $ git status -uall --short
    $ mkdir sub sub/foo; touch sub/foo/bar; echo foo/bar > .gitignore; git status -uall -s
    ?? .gitignore
    ?? sub/foo/bar
    $ echo '**/foo/bar' > .gitignore; git status -uall -s
    ?? .gitignore
    $ 
    

    In other words, to get Git to ignore the file foo/bar within subdirectory sub, we had to write **/foo/bar in the top level .gitignore, because foo/bar does not match sub/foo/bar.

    Note that the rules are different for ignore entries that do not contain an embedded slash. That is:

    $ echo bar > .gitignore
    $ git status -uall -s
    ?? .gitignore
    $ 
    

    Here we do not need the leading **/. So leading **/ is redundant when the name to be ignored does not contain its own embedded /, but is not redundant when the name to be ignored does contain its own embedded /.

    For a longer treatment of the somewhat odd .gitignore rules, see gitignore rules (applied to a codeigniter stack).

    0 讨论(0)
  • 2021-01-02 08:55

    No, the leading **/ is only obsolete if the remaining pattern does not contain a slash except for a trailing one.

    The documentation at https://git-scm.com/docs/gitignore is a bit misleading in my opinion, as it states

    If the pattern does not contain a slash /, Git treats it as a shell glob
    pattern and checks for a match against the pathname relative to the
    location of the .gitignore file (relative to the toplevel of the work
    tree if not from a .gitignore file).
    

    but actually matches only against the name of a file or directory, not the whole path.

    So **/packages/build matches packages/build in any depth.
    packages/build as it contains a slash is effectively the same as /packages/build and only matches packages/build on the same level as the ignore file.

    On the other hand build matches build in any depth so is effectively the same as **/build.
    Whereas /build only matches build on the same level as the ignore file.

    It always depends on whether the pattern (after removing a trailing slash if present) contains any slashes or not.

    0 讨论(0)
提交回复
热议问题