gitignore

Git command to show which specific files are ignored by .gitignore


I am getting my feet wet with Git and have the following issue:

My project source tree:

/
|
+--src/
+----refs/
+----...
|
+--vendor/
+----...

I have code (currently MEF) in my vendor branch that I will compile there and then move the references into /src/refs which is where the project picks them up from.

My issue is that I have my .gitignore set to ignore *.dll and *.pdb. I can do a git add -f bar.dll to force the addition of the ignored file which is ok, the problem is I can not figure out to list what files exist that are ignored.

I want to list the ignored files to make sure that I don't forget to add them.

I have read the man page on git ls-files and can not make it work. It seems to me that git ls-files --exclude-standard -i should do what I want. What am I missing?


Solution

  • Notes:


    Also interesting (mentioned in qwertymk's answer), you can also use the git check-ignore -v command, at least on Unix (doesn't work in a CMD Windows session, but works in a Windows CMD git bash session)

    git check-ignore -- *
    git check-ignore -v -- *
    

    The second one displays the actual rule of the .gitignore which makes a file to be ignored in your git repo.
    On Unix, using "What expands to all files in current directory recursively?" and a bash4+:

    git check-ignore **/*
    

    (or a find -exec command)

    Note: https://stackoverflow.com/users/351947/Rafi B. suggests in the comments to avoid the (risky) globstar:

    git check-ignore -v $(find . -type f -print)
    

    Make sure to exclude the files from the .git/ subfolder though.

    CervEd suggests in the comments, to avoid .git/:

    find . -not -path './.git/*' | git check-ignore --stdin
    

    Original answer (2009)

    git ls-files -i
    

    should work, except its source code indicates:

    if (show_ignored && !exc_given) {
                    fprintf(stderr, "%s: --ignored needs some exclude pattern\n",
                            argv[0]);
    

    exc_given?

    It turns out it needs one more parameter after the -i to actually list anything.

    Try:

    git ls-files -i --exclude-from=[Path_To_Your_Global].gitignore
    

    (but that would only list your cached (non-ignored) object, with a filter, so that is not quite what you want)


    Example:

    $ cat .git/ignore
    # ignore objects and archives, anywhere in the tree.
    *.[oa]
    $ cat Documentation/.gitignore
    # ignore generated HTML files,
    *.html
    # except foo.html which is maintained by hand
    !foo.html
    $ git ls-files --ignored \
        --exclude='Documentation/*.[0-9]' \
        --exclude-from=.git/ignore \
        --exclude-per-directory=.gitignore
    

    Actually, in my 'gitignore' file (called 'exclude'), I find a command line that could help you:

    F:\prog\git\test\.git\info>type exclude
    # git ls-files --others --exclude-from=.git/info/exclude
    # Lines that start with '#' are comments.
    # For a project mostly in C, the following would be a good set of
    # exclude patterns (uncomment them if you want to use them):
    # *.[oa]
    # *~
    

    So....

    git ls-files --ignored --exclude-from=.git/info/exclude
    git ls-files -i --exclude-from=.git/info/exclude
    
    git ls-files --others --ignored --exclude-standard
    git ls-files -o -i --exclude-standard
    

    Should do the trick.

    (Thanks to honzajde pointing out in the comments that git ls-files -o -i --exclude-from... does not include cached files: only git ls-files -i --exclude-from... (without -o) does.)

    As mentioned in the ls-files man page, --others is the important part, to show you non-cached, non-committed, normally ignored files.

    --exclude_standard is not just a shortcut, but a way to include all standard "ignored patterns" settings.

    exclude-standard
    Add the standard git exclusions: .git/info/exclude, .gitignore in each directory, and the user's global exclusion file.


    Git 2.44 (Q1 2024), batch 13, clarifies the documentation where the --exclude-per-directory option was marked as deprecated, which confused readers into thinking there may be a plan to remove it in the future, which was not our intention.

    See commit 0009542 (24 Jan 2024) by Junio C Hamano (gitster).
    (Merged by Junio C Hamano -- gitster -- in commit bbc8c05, 02 Feb 2024)

    ls-files: avoid the verb "deprecate" for individual options

    When e750951 ("ls-files: guide folks to --exclude-standard over other --exclude* options", 2023-01-13, Git v2.40.0-rc0 -- merge listed in batch #13) updated the documentation to give greater visibility to the --exclude-standard option, it marked the --exclude-per-directory option as "deprecated".

    While it is technically correct that being deprecated does not necessarily mean it is planned to be removed later, it seems to cause confusion to readers, especially when we merely mean

    The option Y can be used to achieve the same thing as the option
    X much simpler. To those of you who aren't familiar with either
    X or Y, we would recommend to use Y when appropriate.
    

    This is especially true for --exclude-standard vs the combination of more granular --exclude-from and --exclude-per-directory options.
    It is true that one common combination of the granular options can be obtained by just giving the former, but that does not necessarily mean a more granular control is not necessary.

    State the reason why we recommend readers --exclude-standard in the description of --exclude-per-directory, instead of saying that the option is deprecated.
    Also, spell out the recipe to emulate what --exclude-standard does, so that the users can give it minute tweaks (like "do the same as Git Porcelain, except I do not want to read the global exclusion file from core.excludes").

    git ls-files now includes in its man page:

    directory and its subdirectories in . If you are trying to emulate the way Porcelain commands work, using the --exclude-standard option instead is easier and more thorough.

    git ls-files now includes in its man page:

    Generally, you should be able to use --exclude-standard when you want the exclude rules applied the same way as what Porcelain commands do. To emulate what --exclude-standard specifies, you can give --exclude-per-directory=.gitignore, and then specify:

    1. The file specified by the core.excludesfile configuration variable, if exists, or the $XDG_CONFIG_HOME/git/ignore file.

    2. The $GIT_DIR/info/exclude file.

    via the --exclude-from= option.