Git exclude: include only specific directory and its subdirectories

Problems

I’ve looked at all the relevant questions on SO, so if the answer does happen to be in there, I apologize.

Here’s the problem: I want to exclude everything but one directory and all of its contents (including sub directories).
The working dir is a WordPress install, and for this specific repo I only want to include wp-content/themes/*
The only way I can get it to work, is if I do this:

Read More
# Blacklist everything
*
# Whitelist all directories
!*/
# Whitelist anything you want to include
!wp-content/themes/*
!wp-content/themes/*/*
!wp-content/themes/*/*/*
!wp-content/themes/*/*/*/*
!wp-content/themes/*/*/*/*/*
!wp-content/themes/*/*/*/*/*/*
!wp-content/themes/*/*/*/*/*/*/*
!wp-content/themes/*/*/*/*/*/*/*/*
!wp-content/themes/*/*/*/*/*/*/*/*/*
!wp-content/themes/*/*/*/*/*/*/*/*/*/*
!wp-content/themes/*/*/*/*/*/*/*/*/*/*/*

Now this seems silly and feels like I’m doing it wrong. It will also not work for directories with more levels than specified here. The * line seems to tell Git to ignore any sub-directory, even if the negating pattern seems to include it.

Solutions

Both of the following answers work:
#1

*
!*/
!wp-content/themes/**

#2

*
!wp-content/
!wp-content/themes/
!wp-content/themes/**

#3

/*
!/wp-content
/wp-content/*
!/wp-content/themes

Could anyone tell me if one is more efficient than the other, or is it purely preference?

Related posts

3 comments

  1. You use ** to match all subdirectories. This should work:

    *
    !wp-content/
    !wp-content/themes/
    !wp-content/themes/**
    
  2. In a very large repo Klas Mellbourn’s answer shows how to avoid enough unnecessary scans that it’ll save noticeable time (just like find on a big tree) the first time, but they tend to stay cached. For almost everything your !*/ followed by any content inclusions works great. So:

    *
    !*/
    !wp-content/themes/**
    

    It also gets you one-directory-per-line inclusion no matter how deep it is.

  3. My take on it:

    Ignore everything in this folder (the root folder) except wp-content, and then ignore everything inside wp-content except themes.

    This way you are not ignoring everything and having to readd it back, only the 2 folders you want to track. (The /* line goes as is, it is not a comment)

    /*
    !/wp-content
    /wp-content/*
    !/wp-content/themes
    

Comments are closed.