Search code examples
gitgitignore

Show all ignored files in git


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


Solution

  • 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