Git – How to ignore all files inside one directory recursively but some files with an specific extension

I’m using Windows 7 with Git v2.8.3.

I have this directory structure which contains a Git repository.

  • How to make a custom merge in multiple branchs?
  • EGit/GitHub on eclipse/pydev : how to push my new code?
  • Git merge doesn't use default merge message, opens editor with default message
  • Why does my remote Git repository have uncommitted changes after pushing to it?
  • .gitignore for all except Jenkins job config files
  • How do I run git bisect only on commits that changed a certain file?
  • testing_gitignore
    │   .gitignore
    │   file_1.txt
    │   file_2.txt
    │
    ├───dir_1
    │       file_11.txt
    │       file_12.txt
    │       file_13.txt
    │
    └───dir_2
        │   file_21.txt
        │   file_22.txt
        │   file_23.xlsx
        │   file_24.txt
        │
        └───dir_21
                file_211.txt
                file_212.xlsx
                file_213.txt
    

    I wanna configure the .gitignore file in order to ignore all files inside dir_2 recursively but keeping (for commit) the files with extension: .xlsx (recursively).

    Inside .gitignore I used the following:

    /dir_2/*
    /dir_2/**/*
    !/dir_2/*.xlsx
    !/dir_2/**/*.xlsx
    

    But I get no success because I get as files to commit the following list (which you can see also here):

    .gitignore
    file_1.txt
    file_2.txt
    dir_1\file_11.txt
    dir_1\file_12.txt
    dir_1\file_13.txt
    dir_2\file_23.xlsx
    

    but I expect it should be included (as file to commit) the file:

    dir_2/dir_21/file_212.xlsx
    

    Could you give me a .gitignore configuration to achieve this?
    (before posting here could you try it by yourself with the directory structure I attached before for download on the link?)

  • git gc --aggressive vs git repack
  • Git interactive-rebase across multiple branches
  • What is little red arrow and no sign in github desktop?
  • Passing ssh options to git clone
  • Git-Bash Command Prompt won't open up after upgrading to Windows 10
  • Git: How to revert 2 files that are stubbornly stuck at “Changed but not committed”?
  • One Solution collect form web for “Git – How to ignore all files inside one directory recursively but some files with an specific extension”

    Try to ignore files but re-include folders:

    /dir_2/**/*
    !/dir_2/**/
    

    (Note the /**/* of the first rule: it ignores all files and folders recursively, then re-include folders !/**/ in the second rule).

    Then you can re-include files (because their folders are not ignored)

    !/dir_2/**/*.xlsx
    

    The main rule about .gitignore remains:

    It is not possible to re-include a file if a parent directory of that file is excluded.

    So ignoring files and folders (with ‘/**/*‘) means you won’t be able re-include files unless their parent folders are themselves re-included (with !/**/: trailing slash means ‘folders’).
    Full .gitignore:

    /dir_2/**/*
    !/dir_2/**/
    !/dir_2/**/*.xlsx
    

    Note that you don’t have to commit a .gitignore to test its effect: modify it, and do a git status: as long as those files where not tracked (do a git rm -r --cached dir_2 first), the effect of those rules will be immediate.

    With that .gitignore in place, do a git add ., and a git status: it should only show *.xlsx under dir_2/ as being added.

    [ pay attention to the underscores ]

    Git Baby is a git and github fan, let's start git clone.