Git命令显示.gitignore忽略哪些特定文件


644

我被Git弄湿了,并遇到以下问题:

我的项目源代码树:

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

我的供应商分支中有代码(当前为MEF),我将在此处进行编译,然后将引用移至/src/refs项目从中进行引用的地方。

我的问题是我不得不.gitignore忽略*.dll*.pdb。我可以git add -f bar.dll强制添加被忽略的文件,这是可以的,问题是我无法弄清楚列出哪些文件被忽略了。

我想列出被忽略的文件,以确保我不会忘记添加它们。

我已经阅读了手册页git ls-files,但无法使其正常工作。在我看来,git ls-files --exclude-standard -i应该做我想做的。我想念什么?


12
这些天,您将不再使用git-ls-files,而是使用git-ls-files
wojo

7
我恳求你检查利雅得的答案是正确的,因为这是唯一一个承认有没有保证的方式做到这一点只使用Git命令(包括git clean招)作为证明这里。另外,我建议您不要在摘要中使用“排除-来自”示例,因为实际上它并不关注任何.gitignore文件。我之所以特别提出这一要求,是因为该页面是Google的最高回复。
亚历山大·伯德

关于“行之有效的摘要”的简要说明:“ Git ls-files”手册页解释说,“-i”表示包含ls输出的排除文件。我有同样的误解,直到我读到“慢慢来”。;-)

2
答案应放在答案帖中,而不是对问题的编辑。
Flimm

我有git config --global alias.ls ls-files --exclude-standard,那就是这个问题的答案git ls -i
jthill

Answers:


661

笔记:


同样有趣(在qwertymk答案中提到),您也可以git check-ignore -v至少在Unix上使用命令(在CMD Windows会话中不起作用

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

第二个显示的实际规则,该规则.gitignore使git repo中的文件被忽略。
在Unix上,使用“ 什么递归扩展到当前目录中的所有文件? ”和bash4 +:

git check-ignore **/*

(或find -exec命令)

注:https://stackoverflow.com/users/351947/Rafi B.建议在评论避免(风险)globstar

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

但是,请确保从.git/子文件夹中排除文件。


原答案42009)

git ls-files -i

应该工作,除了其源代码指示:

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

exc_given

事实证明,-i要实际列出任何内容,还需要一个参数:

尝试:

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

(但这只会列出带有过滤器的缓存(非忽略)对象,因此并不是您想要的)


例:

$ 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

实际上,在我的“ gitignore”文件(称为“ exclude”)中,我找到了一个可以帮助您的命令行:

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]
# *~

所以....

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

应该可以。

正如ls-files手册页中提到的那样,--others它是重要的组成部分,以便向您显示非缓存的,未提交的,通常被忽略的文件。

--exclude_standard不仅是捷径,而且是包括所有标准“忽略模式”设置的方式。

exclude-standard
添加标准的git排除:.git/info/exclude.gitignore在每个目录和user's global exclusion file


@VocC,根据我对这些测试的理解,您在顶部建议的答案可能存在很大的缺陷。这就是为什么我通常会推荐里亚德的答案
亚历山大·伯德

2
自Git v2.13.2发布以来:git status --ignored似乎还显示了未跟踪的文件:github.com/git/git/blob/master/Documentation/RelNotes/…–
Pau

1
哇,git check-ignore -v *效果很好,因为它显示了配置的应用位置。谢谢。
Hoang Tran

@MikeD要使* /起作用(或者实际上,您可以做**),您需要shopt -s globstar在它可以起作用之后设置globstar 。
Veda

没有启用(风险)globstar:git check-ignore -v $(find . -type f -print)
拉菲

480

有一种简单得多的方法(git 1.7.6+):

git status --ignored

请参见是否有一种方法可以告诉git-status忽略.gitignore文件的影响?


3
您正在使用什么版本的git?我的(1.7.0.4)说error: unknown option 'ignored'。即使-s按链接文章中的建议添加也不起作用。
亚历山大·伯德

3
我的版本是1.7.6。需要的版本是1.7.5.1 -s。您可以尝试git status -h看看是否--ignored受支持
Penghe Geng 2012年

1
我想1.7.0.4尚不支持。我的另一台计算机上有1.7.9,那里有--ignored标志
Alexander Bird

4
我尝试了此页面上的所有解决方案。这是最好的。它显示文件和目录。最初询问此问题时,可能无法使用此功能。(顺便说一句,直到您至少进行了更改,所有解决方案都无法在全新的“ git init”下正常工作。)
wisbucky 2013年

12
这肯定比接受的答案好得多。它也比git clean -ndX解决方案安全得多,因为在极少数情况下,如果错误地忘记了标志,将删除存储库,从而对存储库产生不可挽回的影响。因此很危险。相反git status --ignored,即使输入错误也总是安全的,并且很容易记住。
Ioannis Filippidis

400

另一个很干净的选择(无双关语):

git clean -ndX

说明:

$ 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.

注意:此解决方案将不会显示已删除的忽略文件。


不错...但是我问原始问题的原因是,我可以确保应该存在的供应商文件(* .dll)...因此删除它们将不是理想的结果。但是,这很高兴,因为我将策略从忽略* .dll更改为忽略生成输出文件夹(但没有更改供应商文件夹)。这将是make clean构建服务器的替代品,并且对构建服务器非常有帮助。
安德鲁·伯恩斯

2
我正在使用git版本1.7.0.4,这两个命令('git ls-files -o -i -exclude-standard','git clean -dXn')并不等效。第一个显示了4个文件,第二个显示了两个文件。(.gitignore〜,index.php〜,sql / create_users.sql〜,www / index.php〜)(将删除.gitignore〜,将删除index.php〜)。我在这里想念东西吗?
Cesar

@VonC,太好了!谢谢!@Cesar,我不确定。我不太熟悉git ls-files -o -i --exclude-standardgit clean -dXn一直是我想要的,但不显示已删除的忽略文件。git ls-files -o -i --exclude-standard可能会做到这一点。因此,这可能是造成差异的原因。
ma11hew28 2011年

3
一个小小的事情-键入第n一个可能会是个好主意,这样可以减少意外删除的机会;git clean -ndX
Tobias Cohen

1
@TobiasCohen真好!我用您的建议更新了答案。更安全 虽然,如果您省略n,则Git默认为fatal: clean.requireForce defaults to true and neither -n nor -f given; refusing to clean。还是很安全的,但是输入第n一个甚至更安全!:)
ma11hew28 2011年

39

虽然通常正确,但是您的解决方案并非在所有情况下都有效。假设这样的仓库目录:

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

doc:
index.html

tmp:
dir0  file1  file2

tmp/dir0:
file0

和.gitignore像这样:

# cat .gitignore
doc
tmp/*

这将忽略doc目录和下面的所有文件tmp。Git可以按预期工作,但是用于列出被忽略文件的给定命令却没有。让我们看看git会说些什么:

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

请注意,doc列表中缺少该属性。您可以通过以下方式获得它:

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

注意其他--directory选项。

据我所知,没有一个命令可以一次列出所有被忽略的文件。但我不知道为什么tmp/dir0不出现。


2
这给了我我想要的东西,而其他人则没有(对于我的特殊情况)...谢谢!必须运行两个命令令人沮丧,但是对于一个被忽略的目录,--directory选项至少可以找到我,并且可以将其通过管道传递给find命令来查找文件。谢谢!
林德斯

这可以一次完成所有操作,并扩展目录:(git ls-files -oi --exclude-standard; git ls-files -oi --exclude-standard --directory) | perl -nle '$seen{$_}++||next;if(-d){system"find",$_,"-type","f"}else{print}'
Dee Newcum 2012年


13

使用就足够了

git ls-files --others -i --exclude-standard

因为这涵盖了

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

因此,后者是多余的。


您可以通过在~/.gitconfig文件中添加别名来简化此操作:

git config --global alias.ignored "ls-files --others -i --exclude-standard"

现在,您只需键入git ignored即可查看列表。记住起来容易得多,输入起来也更快。

如果您希望更简洁地显示Jason Geng的解决方案,则可以为此添加一个别名:

git config --global alias.ignored "status --ignored -s"

但是,更详细的输出对于解决.gitignore文件的问题更有用,因为它列出了每个被忽略的棉花文件。通常,您可以通过管道传递结果,grep以查看其中是否包含您希望忽略的文件,或者其中是否包含了您不想忽略的文件。

git ignored | grep some-file-that-isnt-being-ignored-properly

然后,当您只想查看简短的显示时,就很容易记住和键入

git status --ignored

-s通常可以将其保留。)


这对我从来没有用过,因为您必须手动列出这些文件。git status --ignored在Debian sid上工作,但可能是非常新的……但显然是由于受欢迎的需求而增加的;-)
mirabilos 2013年

1
通过“在Debian sid上运行”,我假设您的意思是“与在Debian sid上默认安装的Git版本兼容”?您应该真正避免让发行版中包含的实用程序版本成为人质。您可以独立于发行版本身升级它们。
iconoclast

12

这是在工作树中打印与位于Git多个gitignore源中任何位置的模式匹配的文件的完整列表的方式(如果您使用的是GNU find):

$ cd {your project directory}
$ find . -path ./.git -prune -o -print \
| git check-ignore --no-index --stdin --verbose

它将检查存储库当前分支中的所有文件(除非您已在本地删除它们)。

并且它还标识特定的gitignore源代码行。

Git继续跟踪某些匹配gitignore模式的文件中的更改,仅仅是因为这些文件已被添加。有用的是,上述命令也可以显示这些文件。

负的gitignore模式也被匹配。但是,由于它们以开头,因此在清单中很容易区分它们!

如果您使用的是Windows,则Git Bash包含GNU find(如所示find --version)。

如果列表很长(并且您有rev),则也可以通过扩展名(某种程度上)显示它们:

$ cd {your project directory}
$ find . -path ./.git -prune -o -print \
| git check-ignore --no-index --stdin --verbose \
| rev | sort | rev

欲了解更多详情,请参阅man findman git-check-ignoreman rev,和man sort

整个方法的重点在于,Git(软件)正在快速变化并且非常复杂。相比之下,GNU的find稳定(至少,在这里使用其功能)。因此,任何希望通过展示其对Git的深入了解来提高竞争力的人都会以不同的方式回答这个问题。

最好的答案是什么?这个答案故意最小化了对Git知识的依赖,从而通过模块化(信息隔离)实现了稳定性和简单性的目标,并且设计了长时间。


非常感谢!我一直在努力弄清楚为什么有时候我的提交中缺少一些新的源文件。原来我有一个模式:bin *,我以为只匹配以bin开头的文件/目录的名称,但是它匹配文件/目录的完整路径中所有包含bin的东西!我想,我的问题来自对.gitignore模式匹配的精确语义的误解。您的2行脚本帮助我找到了这个错误!
Nicolas Rouquette 2015年

1

(扩展其他答案)

注意,git check-ignore使用已提交的.gitignore而不是您的工作树中的一个!要使用它而不污染您的git历史记录,您可以自由尝试对其进行编辑,然后使用git commit --amend

发生此问题的主要原因是,如果您需要解决该问题的方法,即git不遵循目录。输入.gitignore

dirtokeep/**
!dirtokeep/.keep

.keep应该是中的零长度文件dirtokeep

其结果将是一切dirtokeep将被忽略,除外 dirtokeep/.keep,这将导致该还的dirtokeep目录将在克隆/结帐构造。


0

假设有一些忽略目录,为什么不使用“ git status node / logs /”,它将告诉您要添加哪些文件?在目录中,我有一个文本文件,该文件不属于状态输出,例如:

在分支机构主服务器上
您的分支机构的最新信息是“ origin / master”。
未跟踪的文件:(
使用“ git add ...”包括在将提交的内容中)

    node/logs/.gitignore 

.gitignore是:

*

!.gitignore

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.