Thursday, March 24, 2011

Show ignored files in git

I am getting my feet wet on 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 add 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?

UPDATE:

git ls-files -i will not work, you get the error: ls-files: --ignored needs some exclude pattern

git-ls-files --others -i --exclude-from=.git/info/exclude as VonC sugested below is indeed the answer. the --exclude-standard option also works instead of --exclude-from.

Summary of what works:

git-ls-files --others -i --exclude-from=.git/info/exclude
git-ls-files --others -i --exclude-standard
From stackoverflow
  • 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 need 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 --others --ignored --exclude-from=.git/info/exclude
    git ls-files -o -i --exclude-from=.git/info/exclude
    
    git ls-files --others --ignored --exclude-standard
    git ls-files -o -i --exclude-standard
    

    should do the trick.

    As mentioned in the ls-files man page, --others is the important part, in order 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.

    Paul : Very nice. I'm continually surprised at what Git can do.
    igorgue : the best documentation, read the source code :)
    VonC : Thank you, dbr, for fixing the style of git commands.
    gatoatigrado : I'm continually surprised at how difficult these things are to find out... compare with $(hg help stat), "-i --ignored show only ignored files"
  • While generally correct your solution does not work in all circumstances. Assume a repo dir like this:

    # ls **/*                                                                                                       
    doc/index.html  README.txt  tmp/dir0/file0  tmp/file1  tmp/file2
    
    doc:
    index.html
    
    tmp:
    dir0  file1  file2
    
    tmp/dir0:
    file0
    

    and a .gitignore like this:

    # cat .gitignore
    doc
    tmp/*
    

    This ignores the doc directory and all files below tmp. Git works as expected, but the given command for listing the ignored files does not. Lets have a look at what git has to say:

    # git ls-files --others --ignored --exclude-standard                                                            
    tmp/file1
    tmp/file2
    

    Notice that doc is missing from the listing. You can get it with:

    # git ls-files --others --ignored --exclude-standard --directory                                                
    doc/
    

    Notice the additional --directory option.

    From my knowledge there is no one command to list all ignored files at once. But I don't know why tmp/dir0 does not show up at all.

  • Another option that's pretty clean (No pun intended.):

    git clean -Xn
    

    Explanation:

    git help clean
    

    git-clean - Remove untracked files from the working tree
    -X - Remove only files ignored by git.
    -n, --dry-run - Don't actually remove anything, just show what would be done.

    Cheers, mate.

    Matt

    P.S. I'm not actually Australian, just proud of my answer. :)

    Andrew Burns : Nifty... however the reason I asked the original question was so that I could make sure that vendor files (*.dll) that were supposed to be there were... so deleting them would not be the desired result. HOWEVER: this is good to know as I have changed my strategy from ignoreing *.dll to ignoring my build output folder (but not my vendor folders). This would be a good alternative to `make clean` and very helpful on a build server.
    MattDiPasquale : Glad to help. When used with the -n option, as shown above, git clean doesn't delete anything.

0 comments:

Post a Comment