哪个gitignore规则是忽略我的文件

有什么办法看到为什么有些文件被忽略git(即.gitignore文件中的哪个规则导致文件被忽略)?

想象一下,我有这个(或更复杂的情况下,有数百个文件夹和数十个.gitignore文件:

 / -.gitignore -folder/ -.gitignore -subfolder/ -.gitignore -file.txt 

如果我运行git add folder/subfolder/file.txt git可能会抱怨它被忽略:

 The following paths are ignored by one of your .gitignore files: folder/subfolder/file.txt Use -f if you really want to add them. 

有没有什么办法知道所有可能的.gitignore有一个规则忽略这个文件,并显示规则? 喜欢:

 The following paths are ignored by your folder/.gitignore file (line 12: *.txt) folder/subfolder/file.txt Use -f if you really want to add them. 

要不就:

 $ git why-is-ignored folder/subfolder/file.txt folder/.gitignore:12:*.txt 
 git check-ignore -v filename 

有关更多详细信息,请参阅手册页 。

原始答案如下:

git目前不提供这样的东西。 但看到你的问题后,我做了一些Googlesearch,发现在2009年这个function被要求和部分实施 。 读完这篇文章之后,我意识到做好这件事并不是太多的工作,所以我已经开始了一个补丁的工作,并且希望在接下来的一两天内完成。 准备就绪后,我会更新这个答案。

更新:哇,比我想象的要困难得多。 git的排除处理的内部是相当神秘的。 无论如何,这是一个几乎完成的一系列提交 ,适用于今天的上游master分支。 testing套件已经完成了99%,但是我还没有完成对--stdin选项的处理。 希望这个周末我能pipe理好,然后把我的补丁提交给git邮件列表。

同时,我绝对欢迎任何能够这样做的人进行testing – 只需从我的git fork克隆,检查check-ignore分支,然后像平常一样编译它。

更新2:完成了! 最新版本是在上面的github,我已经提交补丁系列到git邮件列表进行同行评审。 我们来看看他们的想法

更新3:经过几个月的黑客/补丁评论/讨论/等待,我很高兴能够说这个function现在已经达到了git的master分支 ,并将在下一个版本(1.8.2,预期2013年3月8日)。 这是check-ignore手册页 。 唷,那是比我预期的更多的工作!

更新4:如果你对这个答案是如何演化的,以及这个function是如何实现的完整故事感兴趣的话,请查看GitMinutes播客的第32集 。

更新git 2.8(2016年3月):

 GIT_TRACE_EXCLUDE=1 git status 

请参阅“ validation.gitignore文件的方法 ”

这是下面描述的git check-ignore -v补充。


原始答案:2013年9月(git 1.8.2,然后1.8.5+):

git check-ignore在git 1.8.5 / 1.9(2013年第四季度)中再次提高:

git check-ignore ”遵循与“ git add ”和“ git status ”相同的规则,因为忽略/排除机制不会对已经被跟踪的path生效。
使用“ --no-index ”选项,可以用它来诊断应该忽略哪些path被错误地添加到索引中

https://github.com/flashydave查看提交8231fa6

check-ignore当前显示.gitignore规则如何处理未跟踪的path。 跟踪的path不会生成有用的输出。
这可以防止debugging为什么意外跟踪path,除非首先用git rm --cached <path>从索引中删除该git rm --cached <path>

选项--no-index指示命令绕过检查索引中的path,因此也允许检查跟踪的path。

虽然这种行为偏离了git addgit status的特性,但它的用例不太可能引起用户混淆。

testing脚本增加了检查这个选项与标准忽略,以确保正确的行为。


 --no-index:: 

进行检查时不要看索引。
这可以用来:

  • debugging为什么通过例如git add .跟踪pathgit add . 并没有被用户预期的规则忽略或
  • 当开发模式,包括否定匹配先前添加了git add -f的path。

我在man page中找不到任何东西,但是这里有一个快速和肮脏的脚本,它将检查每个父目录中的文件,看它是否可以被添加。 在包含问题文件的目录中运行它:

 test-add.sh STOP_DIR FILENAME 

其中STOP_DIR是Git项目的顶层目录, FILENAME是问题文件名(没有path)。 它会在层次结构的每一层创build一个同名的空文件(如果它不存在),并尝试使用git add -n来查看它是否可以被添加(它会自行清理)。 它输出的东西类似于:

 FAILED: /dir/1/2/3 SUCCEEDED: /dir/1/2 

剧本:

 #!/usr/bin/env bash TOP=$1 FILE=$2 DIR=`pwd` while : ; do TMPFILE=1 F=$DIR/$FILE if [ ! -f $F ]; then touch $F TMPFILE=0 fi git add -n $F >/dev/null 2>&1 if [ $? = 0 ]; then echo "SUCCEEDED: $DIR" else echo "FAILED: $DIR" fi if [ $TMPFILE = 0 ]; then rm $F fi DIR=${DIR%/*} if [ "$DIR" \< "$TOP" ]; then break fi done