解释哪个gitignore规则忽略了我的文件

时间:2012-08-27 15:07:07

标签: git 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

6 个答案:

答案 0 :(得分:578)

git check-ignore -v filename

有关详细信息,请参阅the man page

原始答案如下:

git目前不提供此类内容。但在看到你的问题后,我做了一些谷歌搜索,并在2009年发现this feature was requested and partially implemented。在阅读完线程之后,我意识到要正确地完成这项工作并不会太多,所以我已经开始研究补丁并希望在接下来的一两天内完成。我准备好后会更新这个答案。

更新:哇,这比我想象的要难得多。 git排除处理的内脏非常神秘。无论如何,这里的an almost finished series of commits适用于今天的上游master分支。测试套件已完成99%,但我还没有完成--stdin选项的处理。希望本周末我会管理它,然后将我的补丁提交到git邮件列表。

与此同时,我绝对欢迎任何有能力的人进行测试 - 只需从my git fork克隆,查看check-ignore分支,并正常编译。

更新2:已经完成了!最新版本在github上面,如上所述,我有submitted the patch series to the git mailing list进行同行评审。让我们看看他们的想法......

更新3 经过几个月的黑客攻击/补丁评论/讨论/等待,我很高兴能够说出this feature has now reached git's master branch,并且可以在下一个发布(1.8.2,预计2013年3月8日)。这是check-ignore manual page。哎呀,这比我想象的要多得多!

更新4 :如果您对此答案的演变以及该功能的实施情况感兴趣,请查看episode #32 of the GitMinutes podcast

答案 1 :(得分:17)

更新git 2。8(2016年3月):

GIT_TRACE_EXCLUDE=1 git status

请参阅“A way to validate .gitignore file

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


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

git check-ignoregit 1.8.5/1.9 (Q4 2013)中再次提升:

  

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

请参阅commit 8231fa6中的https://github.com/flashydave

  

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

     

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

     

虽然此行为偏离git addgit status的特征,但其用例不太可能导致任何用户混淆。

     

扩充测试脚本以针对标准忽略检查此选项以确保正确的行为。


--no-index::
  

进行检查时,请勿查看索引   这可以使用:

     
      
  • 调试路径被跟踪的原因git add .并未被用户或
  • 所期望的规则所忽略   
  • 开发包含否定的模式以匹配先前添加git add -f的路径。
  •   

答案 2 :(得分:4)

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

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 

答案 3 :(得分:2)

可能不是.gitignore-3个可能的忽略原因

文件可能由于以下原因而被忽略:

  1. .gitignore
  2. git update-index --skip-worktree
  3. git update-index --assume-unchanged

另外,如果文件位于.gitignore中并且已经在索引/缓存中暂存,则文件可能会被忽略。

要检查上述列举的情况:

  1. 对于排除.gitignore的两种情况,比较以下输出:

    • git check-ignore --verbose --non-matching --no-index file1 file2 file3
    • git check-ignore --verbose --non-matching file1 file2 file3
  2. git ls-files file1 file2 file3 | grep -E '^S'

  3. git ls-files file1 file2 file3 | grep -E '^[[:lower:]]'

太难了,给我一个别名!

以下别名将覆盖上面列出的所有情况:

ignore = !"bash -c 'diff --unified=999999999 --color=always <(echo a; git check-ignore --verbose --non-matching --no-index . \"$@\") <(echo b; git check-ignore --verbose --non-matching . \"$@\")' - \"$@\" | tail -n+7; git hidden \"$@\" # Show ignore status of arguments. Files included by index are tagged with prepended '+'."
hidden = !"git ls-files -v -- \"$@\"| grep -E '^(S|[[:lower:]])' # S means update-index --skip-worktree, and lower first letter means --assume-unchanged."

评论和最后的"是要复制到您的.gitconfig的行的一部分。

用法:

git ignore file1 file2 file3

答案 4 :(得分:1)

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

* .sublime-project

作为一个例子。我刚刚删除换行符,瞧!它被修复了。

答案 5 :(得分:1)

上下文:我有一个非常相似的问题,我找不到忽略我的文件/文件夹的规则。我尝试了
git check-ignore -v filename
,但是没有结果,或者结果是.gitignore文件中的行号带有空行。
所以问题出在我的文件中未被本地.gitignore文件忽略,但未被本地core.excludes文件忽略(该文件未包含在我的存储库中)。

解决方案:我使用以下命令查找文件的位置:
git config core.excludesfile
,然后打开它并删除有问题的行,就是这样。< / p>

参考:您也可以看看here以获得更多说明。