26

I have the following directory structure and files.

pw-spec/
|-- event_spec.coffee
|-- event_spec.js
|-- integration
|   `-- service
|       |-- auth_spec.coffee
|       |-- auth_spec.js
|       |-- chat_spec.coffee
|       |-- chat_spec.js
|       |-- transport_spec.coffee
|       `-- transport_spec.js
|-- message_spec.coffee
|-- message_spec.js
|-- pw_spec.coffee
|-- pw_spec.js
|-- run.coffee
|-- run.html
|-- run.js
|-- service
|   |-- auth_spec.coffee
|   |-- auth_spec.js
|   |-- chat_spec.coffee
|   |-- chat_spec.js
|   |-- stream_spec.coffee
|   `-- stream_spec.js
|-- spec.coffee
|-- spec.js
`-- stub
    |-- stream.coffee
    |-- stream.js
    |-- transport.coffee
    `-- transport.js

4 directories, 27 files

I would like to ignore all *.js files anywhere within pw-spec directory.

However, adding the following patterns to .gitignore doesn't cut it:

pw-spec/*.js
pw-spec/**/*.js

The problem is that the second one only matches js files that are exactly 1 level deep within the tree, while I want to match all js files under pw-spec.

Doing

ls pw-spec/**/*.js

produces [1]:

pw-spec/service/auth_spec.js
pw-spec/service/chat_spec.js
pw-spec/service/stream_spec.js
pw-spec/stub/stream.js
pw-spec/stub/transport.js

As you can see

pw-spec/integration/service/auth_spec.js
pw-spec/integration/service/chat_spec.js
pw-spec/integration/service/transport_spec.js

are missing from [1].

NSGod
  • 22,699
  • 3
  • 58
  • 66
Emil Ivanov
  • 37,300
  • 12
  • 75
  • 90

3 Answers3

9

There are two approaches for this type of situation, depending on your needs.

One solution is to put

# generated files
*.js

in pw-spec/.gitignore.

The second solution is to put:

/pw-spec/*.js
/pw-spec/*/*.js
/pw-spec/*/*/*.js

and so forth in the main .gitignore file.This approach is brittle if more sub-directories are added.

I generally prefer to put the .gitignore file at the same level as the Makefile which generates the files that I am ignoring.

Ben Martin
  • 1,470
  • 2
  • 13
  • 16
  • 3
    This solution still works, but as of 2013, you can do exactly what the OP tried: `pw-spec/**/*.js`. See [this answer](http://stackoverflow.com/a/1470664/5191105). – Isaac Oct 11 '16 at 16:51
8

The difference is that ** doesn't work, at least not for everyone. See

Why doesn't gitignore work in this case?

You can have a separate .gitignore in pw-spec/

Community
  • 1
  • 1
Mischa Arefiev
  • 5,227
  • 4
  • 26
  • 34
2

Create a .gitignore in pw-spec in which you insert these two lines:

*.js
*/*.js

Also note that if you already have files tracked in this subdirectory which you want "untracked", you have to make them unknown to the index as such:

git rm --cached path/to/file

For instance, if in directory pw-spec you can do:

find -type f -name "*.js" | xargs git rm --cached
fge
  • 119,121
  • 33
  • 254
  • 329
  • I've added `.gitignore` in `pw-spec`. However, `*.js` does match only direct descendants of `pw-spec`, and does not match `.js` files within subdirectories. – Emil Ivanov Jan 12 '12 at 09:39
  • Yeah, I was mixing with `.git/info/exclude`... Hold on – fge Jan 12 '12 at 09:42
  • Hmm, that solves it. I put the `.gitignore` file in the parent of `pw-spec` because there is another dir with similar requirements (I've omitted it for brevity). If I don't find a solution I will simply use 2 `.gitignore` files. – Emil Ivanov Jan 12 '12 at 09:53
  • Maybe try a single .gitignore at the root with 'x/*.js' and 'x/*/*.js' for one directory 'x'? (Note: untested) – fge Jan 12 '12 at 10:02
  • that was my first attempt, and it didn't work. It does not match more than 1 level deep (event with `**`). – Emil Ivanov Jan 12 '12 at 10:12
  • I'm afraid this answer is incorrect. The second line (*/*.js) is completely useless, since it only matches files also matched on the first line. – Ben Martin Jun 19 '12 at 14:08