Git command to show which specific files are ignored by .gitignore
GitIgnoreGit Problem Overview
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?
Git Solutions
Solution 1 - Git
Notes:
- xiaobai's answer is simpler (git1.7.6+):
git status --ignored
(as detailed in "Is there a way to tell git-status to ignore the effects of.gitignore
files?") - MattDiPasquale's answer (to be upvoted)
git clean -ndX
works on older gits, displaying a preview of what ignored files could be removed (without removing anything)
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)
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 42009)
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 --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, 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
.
Solution 2 - Git
There is a much simpler way to do it (git 1.7.6+):
git status --ignored
See Is there a way to tell git-status to ignore the effects of .gitignore files?
Solution 3 - Git
Another option that's pretty clean (No pun intended.):
git clean -ndX
Explanation:
$ git help clean
git-clean - Remove untracked files from the working tree
-n, --dry-run - Don't actually remove anything, just show what would be done.
-d - Remove untracked directories in addition to untracked files.
-X - Remove only files ignored by Git.
Note: This solution will not show ignored files that have already been removed.
Solution 4 - Git
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.
Solution 5 - Git
Git now has this functionality built in
git check-ignore *
Of course you can change the glob to something like **/*.dll
in your case
Solution 6 - Git
Here's how to print the complete list of files in the working tree which match patterns located anywhere in Git's multiple gitignore sources (if you're using GNU find
):
$ cd {your project directory}
$ find . -path ./.git -prune -o -print \
| git check-ignore --no-index --stdin --verbose
It will check all the files in the current branch of the repository (unless you've deleted them locally).
And it identifies the particular gitignore source lines, as well.
Git continues to track changes in some files which match gitignore patterns, simply because those files were added already. Usefully, the above command displays those files, too.
Negative gitignore patterns are also matched. However, these are easily distinguishable in the listing, because they begin with !
.
If you're using Windows, Git Bash includes GNU find
(as revealed by find --version
).
If the list is long (and you have rev
), you can display them by extension (somewhat), too:
$ cd {your project directory}
$ find . -path ./.git -prune -o -print \
| git check-ignore --no-index --stdin --verbose \
| rev | sort | rev
For more details, see man find
, man git-check-ignore
, man rev
, and man sort
.
The point of this whole approach is that Git (the software) is changing rapidly and is highly complex. By contrast, GNU's find
is extremely stable (at least, in its features used here). So, anyone who desires to be competitive by displaying their in-depth knowledge of Git will answer the question in a different way.
What's the best answer? This answer deliberately minimizes its reliance on Git knowledge, toward achieving the goal of stability and simplicity through modularity (information isolation), and is designed to last a long time.
Solution 7 - Git
It should be sufficient to use
git ls-files --others -i --exclude-standard
as that covers everything covered by
git ls-files --others -i --exclude-from=.git/info/exclude
therefore the latter is redundant.
You can make this easier by adding an alias to your
~/.gitconfig
file:
git config --global alias.ignored "ls-files --others -i --exclude-standard"
Now you can just type git ignored
to see the list. Much easier to remember, and faster to type.
If you prefer the more succinct display of Jason Geng's solution, you can add an alias for that like this:
git config --global alias.ignored "status --ignored -s"
However the more verbose output is more useful for troubleshooting problems with your .gitignore files, as it lists every single cotton-pickin' file that is ignored. You would normally pipe the results through grep
to see if a file you expect to be ignored is in there, or if a file you don't want to be ignore is in there.
git ignored | grep some-file-that-isnt-being-ignored-properly
Then, when you just want to see a short display, it's easy enough to remember and type
git status --ignored
(The -s
can normally be left off.)
Solution 8 - Git
If you just need a valid list of files ignored (no matter how they got ignored), and without any extra notice and logs.
Once created, anywhere (in Git-bash) run:
git ignore-list
Create it by executing:
git config --global alias.ignore-list "! cd -- \"\${GIT_PREFIX:-.}\" && git ls-files -v \${1:-.} | sed -n -e \"s,^[a-z] \(.*\)$,\${GIT_PREFIX:-./}\1,p\" && git status --ignored --porcelain \${1:-.} 2>/dev/null | sed -n -e \"s/^\(\\!\\! \)\(.*\)$/\2/p\" #"
>Example usage,
>Assuming it's the initial commit and you want to push everything, try:
> >git ignore-list | xargs git add -f >
Notes:
- It's tested and works on both
macOS
andWindows
platforms! - Once you
cd
into a directory, lists only files ignored from that dir (or its sub-dirs). - And lastly, always logs paths relative to root-dir (which contains
.git
dir, no matter what dir youcd
into).
Another useful thing is Human-readability, like if an entire directory is ignored, something like build
or node_modules
, this will log dir-name only.
While git ls-files --others -i --exclude-standard
command logs each and every file (good for xargs
).
Solution 9 - Git
I would just do
git status --porcelain --ignored
and to only list the ignored files
git status --porcelain --ignored | grep '^[!][!] '
Solution 10 - Git
(extending the other answers)
Note, git check-ignore
uses the committed .gitignore
and not the one in your working tree! To play with it without polluting your git history, you might freely try to edit it, and then commit with a git commit --amend
.
This problem happens mainly if you need a workaround of the problem, that git doesn't follow directories. Enter in the .gitignore
:
dirtokeep/**
!dirtokeep/.keep
.keep
should be a zero-length file in dirtokeep
.
The result will be that everything in dirtokeep
will be ignored, except dirtokeep/.keep
, which will result that also the dirtokeep
directory will be constructed on clone/checkout.
Solution 11 - Git
If you want to remove those files by manually deleting them and have your project totally clear of files outside GIT you can run:
rm -rf $(git status --ignored)
WARNING: this will remove force ANY FILE AND DIRECTORY returned by git status --ignored
. Use at your own discretion and only if you know what you're doing.
Solution 12 - Git
Assuming there are a few ignore directories, why not use "git status node/logs/" which will tell you what files are to be added? In the directory I have a text file that is not part of status output, e.g.:
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
(use "git add
node/logs/.gitignore
.gitignore is:
*
!.gitignore