.gitignore exclude folder but include specific subfolder

后端 未结 17 1628
一个人的身影
一个人的身影 2020-11-21 06:36

I have the folder application/ which I add to the .gitignore. Inside the application/ folder is the folder application/language

相关标签:
17条回答
  • 2020-11-21 07:15

    There are a bunch of similar questions about this, so I'll post what I wrote before:

    The only way I got this to work on my machine was to do it this way:

    # Ignore all directories, and all sub-directories, and it's contents:
    */*
    
    #Now ignore all files in the current directory 
    #(This fails to ignore files without a ".", for example 
    #'file.txt' works, but 
    #'file' doesn't):
    *.*
    
    #Only Include these specific directories and subdirectories:
    !wordpress/
    !wordpress/*/
    !wordpress/*/wp-content/
    !wordpress/*/wp-content/themes/
    !wordpress/*/wp-content/themes/*
    !wordpress/*/wp-content/themes/*/*
    !wordpress/*/wp-content/themes/*/*/*
    !wordpress/*/wp-content/themes/*/*/*/*
    !wordpress/*/wp-content/themes/*/*/*/*/*
    

    Notice how you have to explicitly allow content for each level you want to include. So if I have subdirectories 5 deep under themes, I still need to spell that out.

    This is from @Yarin's comment here: https://stackoverflow.com/a/5250314/1696153

    These were useful topics:

    • How do negated patterns work in .gitignore?
    • How do gitignore exclusion rules actually work?

    I also tried

    *
    */*
    **/**
    

    and **/wp-content/themes/**

    or /wp-content/themes/**/*

    None of that worked for me, either. Lots of trial and error!

    0 讨论(0)
  • 2020-11-21 07:16

    @Chris Johnsen's answer is great, but with a newer versions of Git (1.8.2 or later), there is a double asterisk pattern you can leverage for a bit more shorthand solution:

    # assuming the root folder you want to ignore is 'application'
    application/**/*
    
    # the subfolder(s) you want to track:
    !application/language/gr/
    

    This way you don't have to "unignore" parent directory of the subfolder you want to track.


    With Git 2.17.0 (Not sure how early before this version. Possibly back to 1.8.2), using the ** pattern combined with excludes for each subdirectory leading up to your file(s) works. For example:

    # assuming the root folder you want to ignore is 'application'
    application/**
    
    # Explicitly track certain content nested in the 'application' folder:
    !application/language/
    !application/language/gr/
    !application/language/gr/** # Example adding all files & folder in the 'gr' folder
    !application/language/gr/SomeFile.txt # Example adding specific file in the 'gr' folder
    
    0 讨论(0)
  • 2020-11-21 07:16

    I have found a similar case here, where in laravel by default, .gitignore ignores all using asterix, then overrides the public directory.

    *
    !public
    !.gitignore
    

    This is not sufficient if you run into the OP scenario.

    If you want to commit a specific subfolders of public, say for e.g. in your public/products directory you want to include files that are one subfolder deep e.g. to include public/products/a/b.jpg they wont be detected correctly, even if you add them specifically like this !/public/products, !public/products/*, etc..

    The solution is to make sure you add an entry for every path level like this to override them all.

    *
    !.gitignore
    !public/
    !public/*/
    !public/products/
    !public/products/*
    !public/products/*/
    !public/products/*/
    !public/products/*/*
    
    0 讨论(0)
  • 2020-11-21 07:17

    Commit 59856de from Karsten Blees (kblees) for Git 1.9/2.0 (Q1 2014) clarifies that case:

    gitignore.txt: clarify recursive nature of excluded directories

    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. (*)
    (*: unless certain conditions are met in git 2.8+, see below)
    Git doesn't list excluded directories for performance reasons, so any patterns on contained files have no effect, no matter where they are defined.

    Put a backslash ("\") in front of the first "!" for patterns that begin with a literal "!", for example, "\!important!.txt".

    Example to exclude everything except a specific directory foo/bar (note the /* - without the slash, the wildcard would also exclude everything within foo/bar):

     --------------------------------------------------------------
         $ cat .gitignore
         # exclude everything except directory foo/bar
         /*
         !/foo
         /foo/*
         !/foo/bar
     --------------------------------------------------------------
    

    In your case:

    application/*
    !application/**/
    application/language/*
    !application/language/**/
    !application/language/gr/**
    

    You must white-list folders first, before being able to white-list files within a given folder.


    Update Feb/March 2016:

    Note that with git 2.9.x/2.10 (mid 2016?), it might be possible to re-include a file if a parent directory of that file is excluded if there is no wildcard in the path re-included.

    Nguyễn Thái Ngọc Duy (pclouds) is trying to add this feature:

    • commit 506d8f1 for git v2.7.0, reverted in commit 76b620d git v2.8.0-rc0
    • commit 5e57f9c git v2.8.0-rc0,... reverted(!) in commit 5cee3493 git 2.8.0.

    So with git 2.9+, this could have actually worked, but was ultimately reverted:

    application/
    !application/language/gr/
    
    0 讨论(0)
  • 2020-11-21 07:18

    So , since many programmers uses node . the use case which meets this question is to exclude node_modules except one module module-a for example:

    !node_modules/
    
    node_modules/*
    !node_modules/module-a/
    
    0 讨论(0)
提交回复
热议问题