105

I have seen similar questions (1, 2 and 3), but I don't get a proper solution from them.

I need to ignore all files under a particular folder except for a specific file type. The folder is a subdirectory for the root path. Let me name the folder Resources. Since I don't want to complicate things, let me ignore files under all folders named Resources wherever it is.

This is the most common solution (in all the duplicate questions)

# Ignore everything
*

# Don't ignore directories, so we can recurse into them
!*/

# Don't ignore .gitignore
!.gitignore

# Now exclude our type
!*.foo

The problem with this solution is that it stops tracking newly added files (since * ignores all files). I don't want to keep excluding each and every file type. I want normal behaviour where if any new file is added, git status shows it.

I finally got a solution here. The solution is to add another .gitignore file in Resources folder. This works correctly.

Can I achieve the same with one ignore file? I find having many ignore files in different directories a bit clunky.

This is what I'm trying to achieve:

# Ignore everything under Resources folder, not elsewhere
Resources

# Don't ignore directories, so we can recurse into them
!*Resources/

# Now exclude our type
!*.foo

But this gives the opposite output. It ignores *.foo types and tracks other files.

Community
  • 1
  • 1
nawfal
  • 70,104
  • 56
  • 326
  • 368

4 Answers4

124

@SimonBuchan is correct.

Since git 1.8.2, Resources/** !Resources/**/*.foo works.

Community
  • 1
  • 1
Jim G.
  • 15,141
  • 22
  • 103
  • 166
  • 1
    This works for me, slight tweak, I just need to remove directories and everything below them so I did:`DirectoryName1/** DirectoryName1/**/*` for each of them. Firs remove directories but you need the second to remove all file types. – Scala Enthusiast Oct 07 '16 at 09:34
27

The best answer is to add a Resources/.gitignore file under Resources containing:

# Ignore any file in this directory except for this file and *.foo files
*
!/.gitignore
!*.foo

If you are unwilling or unable to add that .gitignore file, there is an inelegant solution:

# Ignore any file but *.foo under Resources. Update this if we add deeper directories
Resources/*
!Resources/*/
!Resources/*.foo
Resources/*/*
!Resources/*/*/
!Resources/*/*.foo
Resources/*/*/*
!Resources/*/*/*/
!Resources/*/*/*.foo
Resources/*/*/*/*
!Resources/*/*/*/*/
!Resources/*/*/*/*.foo

You will need to edit that pattern if you add directories deeper than specified.

Jim G.
  • 15,141
  • 22
  • 103
  • 166
Ben Martin
  • 1,470
  • 2
  • 13
  • 16
  • 2
    Thats sad.. Indeed I will have deeper directories, so I will stick with the first one :( – nawfal Jul 24 '13 at 07:18
  • See further details on same solution here : http://stackoverflow.com/questions/7803689/gitignore-ignore-all-files-in-folder-hierachy-except-one-specific-filetype -- also linked above by OP @nawfal – here Nov 16 '13 at 01:48
10

This might look stupid, but check if you haven't already added the folder/files you are trying to ignore to the index before. If you did, it does not matter what you put in your .gitignore file, the folders/files will still be staged.

  • 6
    If someone runs into this specific use-case, you can use `git rm --cached ` to clear those ignored files out of git while still leaving them in the filesystem. – slothluvchunk Jun 04 '18 at 22:48
9

Either I'm doing it wrongly, or the accepted answer does not work anymore with the current git.

I have actually found the proper solution and posted it under almost the same question here. For more details head there.

Solution:

# Ignore everything inside Resources/ directory
/Resources/**
# Except for subdirectories(won't be committed anyway if there is no committed file inside)
!/Resources/**/
# And except for *.foo files
!*.foo
Aleksander Stelmaczonek
  • 1,350
  • 1
  • 22
  • 29
  • 2
    Yes, this works for me. Adding the `!/Resources/**/` was crucial to have git not ignore subdirectories. – Johnster Jun 04 '18 at 16:38
  • I agree with you , the solution given by [Jim G](https://stackoverflow.com/a/25916709) is invalid in my case. After reviewing the official documentation, I decided that the reason it was invalid was that the parent directory of those target files was still ignored, so using the exclamation mark was invalid, and then I saw your answer.I can work perfectly here. – Andy Feb 14 '21 at 10:16