[英]Unexpected behavior with .gitignore, git-status and git-check-ignore
我将 Git 用于 Windows 版本 2.34.1 x86。 我有一个包含以下内容的文件夹(所有路径名都相对于该文件夹):
.git/
.gitignore
.vs/OS1/FileContentIndex/a
.vs/OS1/v17/Browse.VC.db
.vs/OS1/v17/Solution.VC.db
.vs/OS1/v17/ipch/AutoPCH/a
econv.txt
正如我们所见,文件夹本身在 Git 控制之下。 但是,上面显示的文件或文件夹都没有被暂存或提交,除了已经被跟踪的.gitignore
。
在以下两种情况下,我无法理解git status
与git check-ignore
的不同行为:
情况一
.gitignore
有以下内容:
/.vs/**/
!*/
git status
输出(缩短为有趣的部分)
Untracked files:
(use "git add <file>..." to include in what will be committed)
.vs/OS1/FileContentIndex/
.vs/OS1/v17/Browse.VC.db
.vs/OS1/v17/Solution.VC.db
.vs/OS1/v17/ipch/
econv.txt
git check-ignore -v.vs/OS1/FileContentIndex/
输出
.gitignore:3:!*/ .vs/OS1/FileContentIndex/
这意味着.vs/OS1/FileContentIndex/
不会被忽略。 这与上述 output 的git status
一致。 到目前为止,一切都很好。
情况2
.gitignore
已进行了最低限度的更改,现在包含
/.vs/**
!*/
git status
输出(缩短为有趣的部分)
Untracked files:
(use "git add <file>..." to include in what will be committed)
econv.txt
git check-ignore -v.vs/OS1/FileContentIndex/
输出
.gitignore:3:!*/ .vs/OS1/FileContentIndex/
问题
我了解情况 1 中的行为。 git check-ignore.vs/OS1/FileContentIndex/
告诉我.vs/OS1/FileContentIndex/
没有被忽略,因此git status
将其放入未跟踪文件列表(尚未添加、暂存或提交)。
但我无法理解情况 2 中的行为。在这里, git check-ignore.vs/OS1/FileContentIndex/
产生与情况 1 中相同的 output ,这再次意味着.vs/OS1/FileContentIndex/
不会被忽略。
但是, git status
不再包含在未跟踪文件列表中。 这对我来说似乎不一致,因为如果不忽略它,它应该出现在未跟踪文件列表中,不是吗?
有人可以解释那里发生了什么吗?
Git 从不存储任何目录(文件夹)。 但是.gitignore
指令可以使 Git不查看文件夹内部,所以这里的事情变得混乱。
这条规则:
/.vs/**/
仅适用于文件夹,并告诉 Git“不要查看这些文件夹”。
这条规则:
!*/
也仅适用于文件夹,并告诉 Git:“每次都查看每个文件夹”。 由于第二条规则稍后出现,它会覆盖第一条规则。 由于第二条规则完全覆盖第一条规则,因此第一条规则无关紧要,可以在不改变任何行为的情况下删除。
当您将第一条规则更改为:
/.vs/**
它现在适用于文件夹和文件。 这告诉 Git 对于.vs
中的每个未跟踪文件,不应添加该文件。 由于根据定义,所有文件夹都未跟踪,因此它们也将被“忽略”(即,不查看内部)。 但是,下一个(未更改的)规则会覆盖文件夹的此状态,因此会检查文件夹,即使它们位于.vs/
下。 检查后,这些文件夹中的所有未跟踪文件都会通过第一条规则被忽略。 所以第一条规则现在很重要!
所以:
git status
在未跟踪文件列表中不再有 [.vs/OS1/FileContentIndex/
]。
git status
命令报告未跟踪的文件,而不是未跟踪的文件夹(根据定义,所有文件夹都是未跟踪的,因此这将是嘈杂且无用的)。 但是git status
将通过剥离文件名部分并仅提及包含文件夹来汇总一大堆文件,除非您使用git status
选项之一来防止这种情况发生。
第一个git status
列表:
Untracked files: (use "git add <file>..." to include in what will be committed).vs/OS1/FileContentIndex/.vs/OS1/v17/Browse.VC.db.vs/OS1/v17/Solution.VC.db.vs/OS1/v17/ipch/ econv.txt
真正意思:
.vs/OS1/FileContentIndex/
中的多个文件,未单独列出;.vs/OS1/v17/Browse.VC.db
,单独列出.vs/OS1/v17/Solution.VC.db
,单独列出.vs/OS1/v17/ipch/
中的多个文件,未单独列出econv.txt
,单独列出要使git status
列出某些文件夹中的特定文件,否则这些文件会像这样组合在一起,请使用-uall
或更长的拼写--untracked-files=all
。
换句话说:
git status
output 中列出。 无法添加空文件夹。 另请参阅如何将空目录添加到 Git 存储库? (有一个适用于此的假或半假子模块的技巧)。git status
output 中。 您的第二组.gitignore
规则就是这种情况,即使仔细(递归地)一直向下查看所有子文件夹(根据定义浪费精力),它们也会小心地忽略.vs
文件夹中的所有文件。git status
output 中。 只有当它们被修改时,它们才会被列出。 1 1这里的“修改”包括在“为提交暂存的更改”output 部分中新增或删除的内容。 这是因为这是HEAD
提交和当前索引内容之间的git diff --name-status
。 但是,根据定义,“未暂存以供提交”部分仅包括已删除或修改的文件,而不包括新文件。 这是因为第二部分的 output 来自 Git 索引中的内容和工作树中的内容之间的比较,如果文件不存在于 Git 的索引中,则根据定义它是untracked ,所以任何提及它 - 如果有的话任何此类——属于“未跟踪文件”部分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.