365

有什么方法可以查看为什么某些文件被 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

6 回答 6

734
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手册页。呼,这比我预期的要多得多!

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

于 2012-08-28T21:58:17.123 回答
20

更新 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-ignore在git 1.8.5/1.9 (Q4 2013)中再次改进:

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

请参阅来自https://github.com/flashydave的提交 8231fa6

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

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

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

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


--no-index::

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

  • 调试为什么路径被 eg 跟踪git add .并且没有被用户期望的规则忽略,或者
  • 在开发包括否定的模式以匹配先前添加的路径时git add -f
于 2013-09-23T07:33:35.747 回答
6

可能不是.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
于 2020-08-13T09:27:28.963 回答
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 
于 2012-08-28T19:49:54.833 回答
2

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

* .sublime-project

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

于 2018-02-16T05:23:44.120 回答
2

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

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

参考:您也可以在此处查看更多说明。

于 2020-07-26T14:58:51.080 回答