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

当前回答

它可能不是。gitignore——3个可能被忽略的原因

文件可能会被忽略,原因如下:

.gitignore Git update-index——skip-worktree Git update-index——assume-unchanged

此外,如果一个文件在.gitignore中并且已经在索引/缓存中暂存,那么它可能会被unignore。

检查上述列举的情况:

对于.gitignore排除的两种情况,比较以下输出: Git check-ignore——verbose——non-matching——no-index file1 file2 file3 Git check-ignore——verbose——不匹配file1 file2 file3 | grep -E '^S' 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

其他回答

我在手册页中找不到任何东西,但这里有一个快速和肮脏的脚本,它将检查每个父目录下的文件,看看它是否可以被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 

它可能不是。gitignore——3个可能被忽略的原因

文件可能会被忽略,原因如下:

.gitignore Git update-index——skip-worktree Git update-index——assume-unchanged

此外,如果一个文件在.gitignore中并且已经在索引/缓存中暂存,那么它可能会被unignore。

检查上述列举的情况:

对于.gitignore排除的两种情况,比较以下输出: Git check-ignore——verbose——non-matching——no-index file1 file2 file3 Git check-ignore——verbose——不匹配file1 file2 file3 | grep -E '^S' 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

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

* .sublime-project

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

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

解决方案:我用这个命令寻找文件的位置:git config core。excludesfilethen我打开它,删除了有问题的行,就是这样。

参考:你也可以看一下这里的额外解释。

git check-ignore -v filename

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

原答案如下:

Git目前还没有提供类似的功能。但在看到你的问题后,我在谷歌上搜索了一下,发现早在2009年,这个功能就被要求并部分实现了。在看完帖子后,我意识到要把它做好并不需要太多的工作,所以我已经开始了一个补丁的工作,希望能在接下来的一两天内完成。当这个答案准备好时,我会更新它。

更新:哇,这比我想象的难多了。git的排除处理的内部是相当神秘的。不管怎样,这里有一个几乎完成的提交系列,它适用于今天的上游主分支。测试套件已经完成了99%,但是我还没有完成——stdin选项的处理。希望这个周末我能做到,然后把我的补丁提交到git邮件列表中。

与此同时,我非常欢迎任何能够这样做的人进行测试-只需从我的git分支克隆,检查check-ignore分支,并正常编译它。

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

更新3:经过几个月的黑客/补丁审查/讨论/等待,我很高兴地说,这个特性现在已经到达git的主分支,并将在下一个版本(1.8.2,预计2013年3月8日)中可用。这是检查忽略手册页。哇,工作量比我想象的要大得多!

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