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

我的项目源代码树:

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


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

我的问题是我将.gitignore设置为忽略*.dll*.pdb。我可以执行git add -f bar.dll来强制添加被忽略的文件,这是可以的,问题是我不知道列出哪些文件被忽略了。

我想列出被忽略的文件到请确保不要忘记添加它们。

我已阅读git ls-files上的手册页,无法使它正常工作。在我看来,git ls-files --exclude-standard -i应该可以执行我想要的操作。我想念什么?

评论

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

我恳请您检查riyad的答案是否正确,因为这是唯一一个没有保证的方法可以保证仅使用git命令(包括git clean技巧)来执行此操作,如此处所示。另外,我建议您不要在摘要中使用“排除-来自”示例,因为实际上它并不关注任何.gitignore文件。我之所以特别提出这个要求,是因为该页面是Google的最高回复。

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

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

我有git config --global alias.ls文件--exclude-standard,这使这个问题成为git ls -i。

#1 楼

注意:小白的答案比较简单(git1.7.6 +):git status --ignored
(如“是否有办法告诉git-status忽略.gitignore的影响”中所述)文件?”)

MattDiPasquale的答案(需要投票)git clean -ndX在较旧的git上有效,显示可以删除(不删除任何内容)被忽略文件的预览。


又有趣(在qwertymk的答案中提到),您也可以至少在Unix上使用git check-ignore -v命令(在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 --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

应该做
(感谢honzajde在评论中指出git ls-files -o -i --exclude-from...不包含缓存文件:仅git ls-files -i --exclude-from...(不包含-o )。
如ls-files手册页中所述,--others是重要的部分,目的是向您展示非缓存的,未提交的,通常被忽略的文件。
--exclude_standard不仅是捷径,而且是包括所有标准“忽略模式”设置的方式。

exclude-standard
在每个目录中添加标准git排除项:.git/info/exclude.gitignoreuser's global exclusion file


评论


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

–亚历山大·伯德(Alexander Bird)
2012年10月26日,下午1:27

自Git v2.13.2发布以来:git status-忽略,它似乎还显示未跟踪的文件:github.com/git/git/blob/master/Documentation/RelNotes/…

–保罗
17-6-23在7:09



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

– Hoang Tran
17年7月18日在16:53

@MikeD要使* /工作(或者实际上,您可以做**),您需要将globstar设置为shopt -s globstar,然后它才能工作。

–吠陀
18年1月31日在10:17

不启用(风险)globstar:git check-ignore -v $(查找。-type f -print)

– rafi
1月6日15:49

#2 楼

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

git status --ignored


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

评论


您正在使用什么版本的git?我的(1.7.0.4)说错误:未知选项“已忽略”。甚至按链接文章中的建议添加-s也不起作用。

–亚历山大·伯德(Alexander Bird)
2012年10月25日21:49

我的版本是1.7.6。另一个版本1.7.5.1是需要-s的版本。您可以尝试git status -h来查看是否支持--ignored

–耿鹏和
2012年10月26日14:49

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

–亚历山大·伯德(Alexander Bird)
2012年10月26日在20:59

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

– Wisbucky
13年8月30日在6:13

这肯定比接受的答案好得多。它也比git clean -ndX解决方案安全得多,因为在极少数情况下,错误地忘记了这些标志将对存储库产生不可撤销的影响,因为删除了未跟踪的文件。因此很危险。相反,git状态---ignored始终是安全的,即使输入错误也很自然。

–Ioannis Filippidis
2013年9月15日在21:03



#3 楼

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

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更改为忽略生成输出文件夹(而不是供应商文件夹)。这将是一个很好的选择,可以使构建服务器干净并非常有用。

–安德鲁·伯恩斯(Andrew Burns)
2010-2-26在16:56

我正在使用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〜)。我在这里想念东西吗?

– es撒
2011年6月15日21:00



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

–ma11hew28
2011年6月16日在1:09



一件小事-最好先输入n,减少偶然删除这种方式的机会; git clean -ndX

– Tobias Cohen
2011年11月24日,2:13

@TobiasCohen很好!我用您的建议更新了答案。更安全虽然,如果您忽略n,则Git默认为致命:clean.requireForce默认为true,并且-n和-f都不给出;拒绝清洁。还是很安全的,但是先输入n更安全! :)

–ma11hew28
2011年11月26日,下午5:03

#4 楼

虽然通常正确,但是您的解决方案在所有情况下都无法正常工作。
假设像这样的存储库目录:

# 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根本不显示。

评论


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

– lindes
2012年5月26日晚上11:53

这会立即完成所有操作,并扩展目录:(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年6月26日20:14



#5 楼

Git现在内置了此功能

git check-ignore *


当然,您可以根据自己的情况将glob更改为**/*.dll之类

Git参考资料

评论


git check-ignore ** / *将文件包含在子目录中

–mzimmer
2015年3月17日在2:34

这仅列出了顶级词典。

– Radon8472
17年7月5日在6:32

#6 楼

使用

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


然后,当您只想看一个简短的显示屏时,记住它并输入即可很容易

-s通常可以省去。 )

评论


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

– mirabilos
2013年9月18日14:16在

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

–iconoclast
18-10-24在15:02

#7 楼

以下是在工作树中打印与位于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 revman sort

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

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

评论


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

–尼古拉斯·鲁凯特(Nicolas Rouquette)
2015年11月11日在22:10

#8 楼

(扩展其他答案)

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

此问题主要是在您需要解决该问题的情况下发生的,git没有跟随目录。输入.gitignore

dirtokeep/**
!dirtokeep/.keep


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

结果将是dirtokeep中的所有内容除了dirtokeep/.keep之外,将被忽略,这将导致dirtokeep目录也将在克隆/签出上构建。

#9 楼

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

在分支master上
您的分支是最新的'origin / master'。
未跟踪的文件:
(使用“ git add ...”包含在将提交的内容中)

    node/logs/.gitignore 


.gitignore是:

*
!.gitignore