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

Car*_*rós 291 git gitignore

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

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

/
-.gitignore
-folder/
    -.gitignore
    -subfolder/
              -.gitignore
              -file.txt
Run Code Online (Sandbox Code Playgroud)

如果我运行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.
Run Code Online (Sandbox Code Playgroud)

有没有办法知道哪一个可能.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.
Run Code Online (Sandbox Code Playgroud)

要不就:

$ git why-is-ignored folder/subfolder/file.txt
folder/.gitignore:12:*.txt
Run Code Online (Sandbox Code Playgroud)

Ada*_*ers 606

git check-ignore -v filename
Run Code Online (Sandbox Code Playgroud)

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

原始答案如下:

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集.

  • 人们并不是每天都会看到 Stack Overflow 开发人员做出如此多的更改来实现开发人员功能。哇和尊重。 (6认同)
  • @yourfriendzak毫无疑问,`git check-ignore`存在并在1.8.2中工作.如果行为不符合您的预期,我建议您(重新)阅读手册页,如果仍然没有,请在git邮件列表上提交正确的错误报告.只是说它没有做任何事情并不是很有帮助.我希望你可能在一个非被忽略的文件上运行它并且错误地期望一些输出(尽管我将来可能会在`--verbose`输出模式中添加对`--show-unmatched`的支持). (3认同)
  • 我正在使用1.8.2并且`git check-ignore`没有做任何事情. (2认同)
  • @AdamSpiers 非常感谢你!经过 3 天的调查,您刚刚帮助我找到了由于 .gitignore_global 中全局忽略的文件而导致构建中断的原因!我什至不知道这是一件事! (2认同)

Von*_*onC 17

更新git 2.8(2016年3月):

GIT_TRACE_EXCLUDE=1 git status
Run Code Online (Sandbox Code Playgroud)

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

这与git check-ignore -v下面描述的互补.


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

git check-ignoregit 1.8.5/1.9(2013年第4季度)中再次提高:

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

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

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

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

虽然这种行为从特征偏离git addgit status它的使用情况下是不会对身体造成用户混淆.

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


--no-index::
Run Code Online (Sandbox Code Playgroud)

在进行检查时不要查看索引.
这可以使用:

  • 调试为什么路径被例如跟踪,git add .并且没有被用户或者预期的规则忽略
  • 在开发包含否定的模式以匹配之前添加的路径时git add -f.


Tom*_*ale 10

可能不是.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."
Run Code Online (Sandbox Code Playgroud)

注释和结尾"是要复制到您的.gitconfig.

用法:

git ignore file1 file2 file3
Run Code Online (Sandbox Code Playgroud)


edo*_*lin 5

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

test-add.sh STOP_DIR FILENAME
Run Code Online (Sandbox Code Playgroud)

其中STOP_DIR是 Git 项目的顶级目录,FILENAME是问题文件名(不带路径)。它在层次结构的每个级别创建一个同名的空文件(如果不存在),并尝试查看git add -n是否可以添加它(它会自行清理)。它输出类似:

FAILED:    /dir/1/2/3
SUCCEEDED: /dir/1/2
Run Code Online (Sandbox Code Playgroud)

剧本:

test-add.sh STOP_DIR FILENAME
Run Code Online (Sandbox Code Playgroud)