在git中显示所有被忽略的文件

10

我遇到了一个问题,git ls-files --others --ignored --exclude-standard没有列出一些被忽略的文件。

我的项目有这个目录结构:

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

aspnet/.gitignore 列出了 lib/*, 并且执行 git add aspnet/lib/foo 时会提示该路径被忽略。

但是,git ls-files --others --ignored --exclude-standard 不会列出 lib 目录下的文件。这些是未跟踪的文件,如果我执行 git ls-files --others,它们会出现在输出中,但如果提供已忽略的标志,则不会出现。

使用 git 版本 1.7.9.5

编辑:在 git 版本 1.8.5.2 (Apple Git-48) 中如预期工作,这似乎是一个 git bug。


关于忽略的目录,在 git cleangit ls-files 之间存在微妙的区别——clean 不会进入一个被忽略且完全未跟踪的目录——它的任务是清理工作树,而搜索(完全被忽略的)构建产物树可能会成为一个巨大的时间浪费。因此 clean 看到目录本身被忽略了,并将其忽略掉。然而,git ls-files 将进入这些目录,因为它的任务是列出文件。 - jthill
你尝试过使用 git ls-files --others -i --exclude-standard 命令(加上 -i 选项)吗? - Top-Master
3个回答

22

如果你在 UNIX/Linux 中已经安装了 find,那么你可以在 Git 存储库的根目录下执行以下命令:

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

find . -type f 会遍历目录并列出所有文件,而 git check-ignore 则会从该列表中列出那些实际被 .gitignore 忽略的文件。


check-ignore 命令是相对较新的。如果您的 .git 版本尚不支持它,则可以使用以下基于 POSIX 兼容 shell(如 bash、sh、dash、zsh)的解决方法。这种方法基于这样一个事实: .gitignore 包含通配符模式,这些模式旨在由 shell 解释。解决方法会遍历 .gitignore 中的通配符模式,在 shell 中扩展它们并过滤掉目录。

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

嗯,它没有输出任何东西,但肯定有一些被忽略的文件。.gitignore 文件包含了 "node_modules" 这一行,所以 git 应该忽略任何子路径下的 node_modules 目录。 - lks128
我修复了缺失的 git,c-i 的 -v 选项非常有用,它可以使嵌套的 .gitignore 文件夹在使用时更加方便和愉悦。感谢提供这个命令,即使我认为对于这个特定的问题还有更好的解决方法。 - jthill
@Andrew 哦,我明白了...你使用的是 folder 而不是 folder/*(这很有道理!我的测试数据是来自一个 **** 项目的 .gitignore :))需要改进命令以反映这一点 - 但是明天再说吧,我今天很累了。请还要检查 jthill 的答案... - hek2mgl
2
我认为缺少指定路径,应该是 find . -type f,对吗? - Kamil Seweryn
MacOS版本需要路径,GNU find默认使用当前目录。 - hek2mgl
显示剩余3条评论

4

我的 Kung-Fu 是递归列出所有被忽略的文件,并带有规则。

find . -type d | grep -v .git | awk '{print $1"/"}' | git check-ignore -v --stdin

-type d 表示目录。 -type f 是用于文件。 - TamaMcGlinn
使用-v选项可以方便地查看哪个规则忽略了文件。如果你想查看git将要忽略哪些文件,而不管它们是否已经被跟踪,请添加--no-index选项。 - hsandt

2
在 Windows PowerShell 窗口中执行此操作很简单:

最初的回答

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

输出结果看起来有点奇怪,好像是为Cygwin或bash设计的 - 而我不使用这些 - 所以这可能是我的配置问题,但它仍然非常有用,可以找出为什么忽略该文件。

基于git 2.22.0.windows.1的注释


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接