.gitignore exclusion is not working for a single file

前端 未结 3 1767
被撕碎了的回忆
被撕碎了的回忆 2021-01-04 06:44
$ git --version
git version 2.6.4

I realize this is a duplicate but the other question\'s answers have not helped.

Folder structure

相关标签:
3条回答
  • 2021-01-04 07:05

    tl;dr:

    /dist/**/*.*
    !/dist/**/README.md
    !/dist/samples/*.*
    
    

    Proof it works:

    tree dist -a
    dist
    ├── bar
    │   └── index.html
    ├── baz.js
    ├── foo
    │   └── main.js
    └── samples
        ├── README.md
        └── stuff.jpg
    
    find dist -type f | git check-ignore --verbose --non-matching --stdin
    .gitignore:1:/dist/**/*.*   dist/baz.js
    .gitignore:2:!/dist/samples/*.* dist/samples/stuff.jpg
    .gitignore:2:!/dist/samples/*.* dist/samples/README.md
    .gitignore:1:/dist/**/*.*   dist/foo/main.js
    .gitignore:1:/dist/**/*.*   dist/bar/index.html
    

    Like https://stackoverflow.com/a/35279076/2496472 says, the docs mention:

    An optional prefix "!" which negates the pattern; any matching file excluded by a previous pattern will become included again. It is not possible to re-include a file if a parent directory of that file is excluded. Git doesn’t list excluded directories for performance reasons, so any patterns on contained files have no effect, no matter where they are defined.

    However, the docs also say:

    Two consecutive asterisks ("**") in patterns matched against full pathname may have special meaning:

    • A slash followed by two consecutive asterisks then a slash matches zero or more directories. For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on.

    Putting this together, the strategy is to never ignore a directory but ignore all files within a directory, and then exclude the file you want.

    References:

    • https://git-scm.com/docs/gitignore#_pattern_format
    • https://git-scm.com/docs/git-check-ignore
    0 讨论(0)
  • 2021-01-04 07:13

    I has the similar problem with another .gitignore in subdirectory. For examaple:

    - root
    -- Subdir
    --- gulpfile.js
    --- .gitignore
    -- .gitignore
    

    In root .gitignore where two rules:

    *.js
    !gulpfile.js
    

    And in Subdir/gulpfile.js where another one rule:

    *.js
    

    Because of that, Subdir/gulpfile.js where ignored. To solve problem it is required to remove Subdir/.gitignore, or add !gulpfile.js to Subdir/.gitignore.

    0 讨论(0)
  • 2021-01-04 07:20

    The problem is simply because you are ignoring the directory dist. So Git will no longer look into the directory to look for other files.

    As explained in this related answer, you need to whitelist the directory and only ignore its contents. Since you are having a nested structure, this does end up being a bit complicated though:

    # ignore everything in the `dist` folder
    dist/*
    # … but don’t ignore the `dist/samples` folder
    !dist/samples/
    # … but ignore everything inside that `dist/samples` folder
    dist/samples/*
    # … except the `README.md` there
    !dist/samples/README.md
    

    This is also explicitly mentioned in the gitignore documentation (emphasis mine):

    An optional prefix "!" which negates the pattern; any matching file excluded by a previous pattern will become included again. It is not possible to re-include a file if a parent directory of that file is excluded. Git doesn’t list excluded directories for performance reasons, so any patterns on contained files have no effect, no matter where they are defined.

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