303

Is there a way to ignore all files of a type in a directory?

** is apparently meaningless to git, so this doesn't work:

/public/static/**/*.js

The idea is to match arbitrary nested folders.

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
Harry
  • 52,711
  • 71
  • 177
  • 261
  • 2
    possible duplicate of [Git-ignore certain files in sub-directories, but not all](http://stackoverflow.com/questions/6794717/git-ignore-certain-files-in-sub-directories-but-not-all) – Chris Moschini Jul 31 '14 at 19:03

9 Answers9

294

It would appear that the ** syntax is supported by git as of version 1.8.2.1 according to the documentation.

Two consecutive asterisks ("**") in patterns matched against full pathname may have special meaning:

  • A leading "**" followed by a slash means match in all directories. For example, "**/foo" matches file or directory "foo" anywhere, the same as pattern "foo". "**/foo/bar" matches file or directory "bar" anywhere that is directly under directory "foo".

  • A trailing "/**" matches everything inside. For example, "abc/**" matches all files inside directory "abc", relative to the location of the .gitignore file, with infinite depth.

  • A slash followed by two consecutive asterisks then a slash matches zero or more directories. For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on.

  • Other consecutive asterisks are considered invalid.

joeyhoer
  • 3,587
  • 1
  • 19
  • 23
  • 5
    what's the difference between `xxx/**` and `xxx/`? – Daniel May 24 '16 at 11:53
  • 12
    `xxx/**` targets all the files and directories inside of `xxx` whereas `xxx/` targets the `xxx` directory directly. This really only matters when negating patterns with `!` as "It is not possible to re-include a file if a parent directory of that file is excluded.", so using `xxx/*` or `xxx/**` would be necessary in that case. – joeyhoer May 26 '16 at 14:55
  • 7
    All files with the ending .meta should be ignored by git. How does this work? `**.js` ? – Black Nov 03 '17 at 21:00
  • "Other consecutive asterisks are considered invalid." sums it all – imrok Oct 02 '18 at 10:01
161

Never tried it, but git help ignore suggests that if you put a .gitignore with *.js in /public/static, it will do what you want.

Note: make sure to also check out Joeys' answer below: if you want to ignore files in a specific subdirectory, then a local .gitignore is the right solution (locality is good). However if you need the same pattern to apply to your whole repo, then the ** solution is better.

ptyx
  • 4,074
  • 1
  • 19
  • 21
  • 35
    That's not necessary the best solution. Potentially people will need to dig through different .gitignore files to find why their file is being ignored. Some prefer having all this information in one .gitignore file stored at repo root directory. – haren Mar 24 '16 at 15:58
  • 3
    @haren it's not the only solution - Joey's answer is certainly valid as well. Choose whatever works best for you. I'd argue that ignore rules local to a directory should be in that directory, and that global rules should be global. (Also, this answer is ancient and I don't think ** was supported at the time). – ptyx Mar 24 '16 at 18:46
90

UPDATE: Take a look at @Joey's answer: Git now supports the ** syntax in patterns. Both approaches should work fine.


The gitignore(5) man page states:

Patterns read from a .gitignore file in the same directory as the path, or in any parent directory, with patterns in the higher level files (up to the toplevel of the work tree) being overridden by those in lower level files down to the directory containing the file.

What this means is that the patterns in a .gitignore file in any given directory of your repo will affect that directory and all subdirectories.

The pattern you provided

/public/static/**/*.js

isn't quite right, firstly because (as you correctly noted) the ** syntax is not used by Git. Also, the leading / anchors that pattern to the start of the pathname. (So, /public/static/*.js will match /public/static/foo.js but not /public/static/foo/bar.js.) Removing the leading / won't work either, matching paths like public/static/foo.js and foo/public/static/bar.js. EDIT: Just removing the leading slash won't work either — because the pattern still contains a slash, it is treated by Git as a plain, non-recursive shell glob (thanks @Joey Hoer for pointing this out).

As @ptyx suggested, what you need to do is create the file <repo>/public/static/.gitignore and include just this pattern:

*.js

There is no leading /, so it will match at any part of the path, and that pattern will only ever be applied to files in the /public/static directory and its subdirectories.

Community
  • 1
  • 1
Adam Sharp
  • 3,618
  • 25
  • 29
  • 3
    This is not entirely true – specifically the portion "Removing the leading `/` won't work either, matching paths like `public/static/foo.js` and `foo/public/static/bar.js`." is false. To quote [the documentation](http://git-scm.com/docs/gitignore/) "If the pattern does not contain a slash /, Git treats it as a shell glob pattern and checks for a match against the pathname relative to the location of the .gitignore file (relative to the toplevel of the work tree if not from a .gitignore file)." `foo/public/static/bar.js` would not be matched because the pattern does contain a `/`. – joeyhoer Jan 15 '14 at 20:26
  • @JoeyHoer thanks of the tip, I've updated my answer accordingly. – Adam Sharp Jan 22 '14 at 10:02
21

I have tried opening the .gitignore file in my vscode, windows 10. There you can see, some previously added ignore files (if any).

To create a new rule to ignore a file with (.js) extension, append the extension of the file like this:

*.js

This will ignore all .js files in your git repository.

To exclude certain type of file from a particular directory, you can add this:

**/foo/*.js

This will ignore all .js files inside only /foo/ directory.

For a detailed learning you can visit: about git-ignore

Tuhin Mitra
  • 555
  • 7
  • 19
11

To ignore untracked files just go to .git/info/exclude. Exclude is a file with a list of ignored extensions or files.

Thiago Ramos
  • 649
  • 8
  • 6
  • 3
    This would not carry over to other clones of the repository like .gitignore would (after being committed, of course). – jpmc26 Jul 05 '17 at 23:02
8

As other answers have already said, a pattern like **/*.exe will ignore all .exe files anywhere in your repository.

However, many people (like me) are bound to arrive at this question while troubleshooting...
WHY THIS IS NOT WORKING.

So, the command git status or your IDE may be telling you that xyz.exe is about to be committed, and you may be banging your head against the wall trying to figure out why this is so, since you do in fact have **/*.exe in your .gitignore file, and since this Q&A confirms that this is in fact the correct magical incantation, which should be preventing this. But it doesn't.

The actual reason you are in this preposterous situation is that you (or, more likely, your IDE automagically for you,) has already staged that file.

The solution is to unstage it first, and then it will be ignored.

<rant> The "staging area" is an entirely useless feature of git, which is a major source of pain without any benefit worth speaking of; however, it is central in how git works, so you have to always be aware of it. Different IDEs take different approaches towards it: Visual Studio forces you to deal with staging, and that's one of the reasons why working with git in Visual Studio is a major pain, and a very poor user experience. IntelliJ IDEA handles staging behind the scenes for you, (as it should,) so you do not have to be bothered by it, or even be aware of its existence, and that's one of the reasons why working with git in IntelliJ IDEA is a pleasure. Unfortunately, nothing works perfectly, so inevitably, every once in a while there will be pain, even with IntelliJ IDEA. </rant>

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
  • Visual Studio has a Commit button which acts as "Stage all and Commit" as long as nothing is staged. Once something is manually staged, then it is "Commit all staged". I agree that git is full of usability pitfalls. – Gru Feb 08 '23 at 09:36
5

I believe the simplest solution would be to use find. I do not like to have multiple .gitignore hanging around in sub-directories and I prefer to manage a unique, top-level .gitignore. To do so you could simply append the found files to your .gitignore. Supposing that /public/static/ is your project/git home I would use something like:

find . -type f -name *.js | cut -c 3- >> .gitignore

I found that cutting out the ./ at the beginning is often necessary for git to understand which files to avoid. Therefore the cut -c 3-.

Garini
  • 1,088
  • 16
  • 29
-1

I used git rm --cached **.DS_Store to remove and untracked all the .DS_Store files from the repo.

Gilbert M.
  • 67
  • 4
-2

Few additional tips on top of other answers (which may work if you're lucky and issue is due to some other reason):

  1. Make sure u ignore files larger than 100mb in your code
  2. Just restart the git workflow. Delete the local .git folder and git init again and retry pushing to github.
Baraja Swargiary
  • 381
  • 2
  • 10