10

I'm having problems with git ls-files --others --ignored --exclude-standard not listing some ignored files.

My project has this directory structure

.
├── aspnet
│   ├── .gitignore
│   ├── __init__.py
│   ├── lib
│   │   ├── <lots of big stuff>

The aspnet/.gitignore lists lib/*, and git add aspnet/lib/foo reports that this path is ignored.

But git ls-files --others --ignored --exclude-standard does not list the files under lib. These are untracked files, they show up in output if I do git ls-files --others, but not if I provide the ignored flag.

Using git version 1.7.9.5

Edit: works as expected with git version 1.8.5.2 (Apple Git-48), this seems to be a git bug

mmmmmm
  • 32,227
  • 27
  • 88
  • 117
Hamy
  • 20,662
  • 15
  • 74
  • 102
  • Re ignored directories, there's a subtle difference between `git clean` and `git ls-files` -- `clean` will not descend into an ignored and wholly-untracked directory -- its job is to clean the worktree, and searching (wholly-ignored) build-product trees can become a monster waste of time. So clean sees that the directory itself is ignored, and ignores it. `git ls-files`, however, will descend into those directories, because its job is to list files. – jthill Jul 08 '14 at 00:59
  • 1
    Possible duplicate of [Git command to show which specific files are ignored by .gitignore](https://stackoverflow.com/questions/466764/git-command-to-show-which-specific-files-are-ignored-by-gitignore) – phuclv Aug 18 '17 at 07:22
  • Did you try `git ls-files --others -i --exclude-standard` (with additional `-i` option)? – Top-Master Apr 02 '21 at 17:02

3 Answers3

22

Having find (likely on UNIX/Linux), you can issue the following command in the root folder of your git repository:

find . -type f  | git check-ignore --stdin

find . -type f will list all files in the folder recursively, while git check-ignore will list those files from the list, which are effectively ignored by .gitignore.


The check-ignore command is relatively new. If your .git version does not support it already, you can use the following workaround with a POSIX compatible shell (like bash, sh, dash, zsh). It is based on the fact that .gitignore contains glob patterns which are meant to be interpreted by a shell. The workaround iterates over the glob patterns from .gitignore, expands them in the shell and filters out directories from it:

while read glob ; do
    if [ -d "$glob" ] ; then
        # Be aware of the fact that even out of an ignored 
        # folder a file could have been added using git add -f 
        find "$glob" -type f -exec \
            bash -c "FILE={};[ \$(git status -s \$FILE) == "" ] && echo \$FILE" \;
    else
        for file in "$glob" ; do
            # Again, be aware of files which add been added using -f
            bash -c "FILE={};[ \$(git status -s \$FILE) == "" ] && echo \$FILE" \;
        done
    fi
# Pipe stderr to /dev/null since .gitignore might contain entries for non 
# existing files which would trigger an error message when passing them to find
done < .gitignore 2>/dev/null | sort
arainho
  • 35
  • 6
hek2mgl
  • 152,036
  • 28
  • 249
  • 266
  • It would be good to add first version when check-ignore is available, as there's no such git command on version 1.7.10.4 (running debian) – lks128 Jul 07 '14 at 23:57
  • Oh, thanks for the hint. I could only find out, that the command was added on `Jan 06, 2013`. Meaning it is relatively new. Let me find a workaround, having something in mind... – hek2mgl Jul 08 '14 at 00:03
  • Hmm, it doesn't output anything, but there are definitely some ignored files. .gitignore contains line "node_modules", so git should ignore node_modules directory under any child path. – lks128 Jul 08 '14 at 00:38
  • I fixed the missing `git`, and c-i's `-v` option can be very useful, it can make the difference between exasperation and gratification for nested `.gitignore`s +1 for mentioning the command, even though I think there's a better one for this particular question – jthill Jul 08 '14 at 00:44
  • @Andrew Oh, got it... you have `folder` instead of `folder/*` (what makes sense!, my test data was a .gitignore from a **** project :) ) Need the enhance to command to reflect this - but tomorrow, I'm tired for today.. Please also check jthill's answer... – hek2mgl Jul 08 '14 at 00:44
  • wow, thanks for the serious assist. check-ignore is not available in my version of git either (yay outdated ubuntu repo's!), but tbe shell worked – Hamy Jul 08 '14 at 04:11
  • 2
    I think find is missing path specified, should be `find . -type f` no? – Kamil Seweryn Apr 07 '17 at 11:17
  • The MacOS version needs the path, GNU find is using the current directory by default. – hek2mgl Apr 07 '17 at 12:07
4

My Kung-Fu to list all ignored files recursively with rules

find . -type d | grep -v .git | awk '{print $1"/"}' | git check-ignore -v --stdin
Arthur
  • 2,601
  • 1
  • 22
  • 19
  • -type d indicates directories. -type f is for files. – TamaMcGlinn Sep 13 '18 at 14:43
  • `-v` to show which rule is responsible for ignoring the file is indeed convenient. If you want to see which files would be ignored by git independently of whether they are already tracked or not, add `--no-index`. – hsandt Apr 13 '19 at 22:56
2

Doing this in a Windows PowerShell windows is straightforward:

PS> Get-ChildItem -Recurse | Select-Object Fullname | git check-ignore --stdin -v

The output does look kinda funky, as if it's designed for Cygwin or bash - which I don't use - so this may be my own misconfiguration, but it's still really helpful for finding out why that file is being ignored.

Comments based on git 2.22.0.windows.1

Steve Friedl
  • 3,929
  • 1
  • 23
  • 30