说明哪个gitignore规则忽略了我的文件


310

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

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

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

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

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

4
注意:git check-ignore很快(git1.8.5 / 1.9)会有一个--no-index选择。请参阅下面的答案
VonC

注意:GIT_TRACE_EXCLUDE=1 git status很快将成为调试.gitignore规则的另一种方法。请参阅下面我编辑的答案
VonC

相关博客文章:danielcompton.net/2016/04/21/…
krlmlr

Answers:


643
git check-ignore -v filename

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

原始答案如下:

git当前不提供任何此类信息。但是在看到您的问题后,我进行了一次谷歌搜索,发现早在2009年,此功能就被要求并部分实现。读完该线程后,我意识到适当地完成它并不需要太多工作,因此我开始着手开发补丁程序,并希望在第二天或第二天完成它。准备好后,我将更新此答案。

更新:哇,这比我预期的要难得多。的内部结构git的处理排除是相当神秘。总之,这里是一个几乎完成一系列提交其适用于今天的上游master分支。测试套件已完成99%,但我尚未完成该--stdin选项的处理。希望这个周末能解决这个问题,然后将补丁提交到git邮件列表。

同时,我绝对欢迎有能力的人进行测试-从我的gitfork中克隆出来,检出check-ignore分支,然后正常进行编译。

更新2:完成了!如上所述,最新版本位于github上,我已将修补程序系列提交到git邮件列表中,以供同行评审。让我们看看他们的想法...

更新3:在经过数月的黑客入侵/补丁审查/讨论/等待之后,我很高兴地说该功能现已到达git的master分支,并将在下一个版本中可用(1.8.2,预计第8版) 2013年3月)。这是check-ignore手册页。ew,这比我预期的要多!

更新4:如果您对有关该答案如何演变以及功能实现的完整故事感兴趣,请查看GitMinutes播客的第32集


2
我正在使用1.8.2,git check-ignore并且什么也没做。
zakdances

3
@yourfriendzak毫无疑问地git check-ignore存在并在1.8.2中工作。如果行为不符合您的预期,我建议您(重新)阅读手册页,如果仍然不行,请在git邮件列表中提交正确的错误报告。仅仅说它什么也没做是没有太大帮助的。我希望您可能已经在一个不可忽略的文件上运行了它,并且错误地期望了一些输出(尽管将来我可能会增加--show-unmatched--verbose输出模式的支持)。
亚当·斯皮尔斯

1
@AdamSpiers你是对的。我应该指定执行命令时不打印任何内容。没有错误消息,没有成功消息,没有信息。出现下一个空白提示。因此,我是否正确地假设在某些情况下会出现“无输出”现象?
zakdances

1
@AdamSpiers非常感谢您!经过3天的调查,您刚刚帮助我确定了.gitignore_global中全局忽略的文件导致构建中断的原因!我什至不知道那是一回事!
BenBtg '18年

3
并非每天都能看到Stack Overflow开发人员进行如此多的更改以实现开发人员功能。哇,尊敬。
user3613932 '19

18

更新git 2.8(2016年3月):

GIT_TRACE_EXCLUDE=1 git status

请参阅“ 验证.gitignore文件的方法

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


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

git check-ignoregit 1.8.5 / 1.9(2013年第四季度)再次有所改善:

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

提交8231fa6https://github.com/flashydave

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

该选项--no-index告诉命令绕过索引中路径的检查,因此也允许检查跟踪的路径。

尽管此行为偏离了特性,git add并且git status其用例不太可能引起任何用户困惑。

增强了测试脚本,以针对标准忽略检查此选项,以确保行为正确。


--no-index::

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

  • 调试为什么路径例如git add .被用户跟踪,而未被用户期望的规则忽略,或者
  • 在开发模式(包括否定)以匹配先前添加的路径时git add -f

4

我在手册页中找不到任何内容,但这是一个快速而肮脏的脚本,它将检查每个父目录中的文件,以查看是否可以对其进行git-add'ed。在包含问题文件的目录中运行它,如下所示:

test-add.sh STOP_DIR FILENAME

这里STOP_DIR是Git项目的顶级目录,FILENAME是问题文件名(无路径)。它会在层次结构的每个级别上创建一个同名的空文件(如果不存在),然后尝试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 

1

要添加到使用git check-ignore -v filename(感谢BTW)的主要答案中,我发现我的.gitignore文件阻止了所有内容,因为通配符后有换行符,所以我有:

* .sublime-project

举个例子。我刚刚删除了换行符,瞧!它是固定的。

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.