未跟踪的文件未显示在“git status”中

bxgwgixi  于 2023-04-19  发布在  Git
关注(0)|答案(8)|浏览(188)

我有一个文件夹结构如下的项目:
所有的项目文件都在base_fldr文件夹中。另外,我在base_fldr中有几个文件夹,称为sub_fldr1sub_fldr2。这些子文件夹也包含一些文件。
如果我修改了base_fldrbase_fldr\sub_fldr\中的任何文件,那么git status将显示为已修改。此外,如果我向base_fldr添加新文件,git status将显示为未跟踪的文件。
我的问题是,如果我在base_fldr\sub_fldr\中添加一个新文件,那么git status不会将该文件显示为未跟踪。它甚至不会给予有关该文件的任何信息。
该文件或其扩展名不在我的.gitignore列表中。此外,我确实尝试了git add sub_fldr\file_name,但它既没有给出错误,也没有将该文件添加到索引中。
知道这里发生了什么吗谢谢!

jbose2ul

jbose2ul1#

我发现了问题所在。基本上我的.gitignore文件的第一行是“*/"。这会导致git status命令忽略任何添加到子目录的文件。但有趣的是,如果我修改子文件夹中的任何文件,git status正确地显示它们已修改,因为文件已经在git仓库中,但忽略子文件夹中的新文件。
我通过删除.gitignore文件中不忽略子文件夹中的更改的行来修复我的问题,然后将新文件添加到索引中,然后再次添加回.gitignore中的行,以便它将忽略子文件夹中的任何生成的文件。
感谢所有的回应。

nsc4cvqm

nsc4cvqm2#

这可能是因为您的base_fldr\sub_fldr\目录未被跟踪,如果您运行:

git add base_fldr\sub_fldr\

从您的工作副本根目录中,它将自动添加该目录以及该目录中的其他文件和目录。
默认情况下,git不会显示未被跟踪的目录中的文件。

lfapxunr

lfapxunr3#

我遇到了一个类似的问题,丢失的跟踪文件。在尝试管理跟踪文件的本地修改版本而不必经常避免意外提交的方法时,我运行了以下内容:

git update-index --assume-unchanged my-tracked-file-that-is-awol

我最终放弃了这个想法,但忘记了撤销命令,所以对这个和其他--assume-unchanged文件的后续更改完全丢失了:

git status -u --ignored

我花了一段时间才弄清楚发生了什么,但我只需要反转命令:

git update-index --no-assume-unchanged my-tracked-file-that-is-awol
fiei3ece

fiei3ece4#

你的sub_fldr目录中是否有一个.git子目录?Git可能会认为你试图使用submodules

a0x5cqrl

a0x5cqrl5#

为了调试这样的问题,请通过观察以下两个输出来确定您的.gitignore文件是否是罪魁祸首
参见https://git-scm.com/docs/git-ls-files

  1. git ls-files --other --directory --exclude-standard
    这将显示所有未跟踪的文件,同时遵守.gitignore文件。
  2. git ls-files --other --directory
    这将显示所有未跟踪的文件,而不遵守.gitignore文件。
    无论哪个文件出现在2的输出中,但不出现在1的输出中,由于.gitignore文件中的某些标志,这些文件都不会显示在未跟踪中
bqjvbblv

bqjvbblv6#

下面是问题中描述的另一个原因(git status untracked files list doesn 't include an untracked file in a sub-folder*)。如果文件因为子文件夹中的.gitignore文件 * 而被取消跟踪,那么该文件将不会被包含在git status untracked files list中。

dfty9e19

dfty9e197#

自2011年以来,Git v1.8.3-rc 0(2013年4月)首次修复了这一问题。
它修复了代码中的一些问题,以遍历工作树来查找未跟踪和/或忽略的文件,清理和优化代码路径。
参见commit 0aaf62bcommit defd7c7commit 8aaf8d7commit b07bc8ccommit 95c6f27commit 6cd5c58commit 46aa2f9commit 5bd8e2dcommit be8a84ccommit c94ab01commit 184d2a8commit 0104c9ecommit 289ff55commit 560bb7a(15 Apr 2013)by Karsten Blees ( kblees )
(由Junio C Hamano -- gitster --合并至commit 7093d2c,2013年4月23日)

dir.c:使'git-status --ignored'在引导目录中工作

签署人:卡斯滕·布利斯
如果“path”的某些组件被分类为未跟踪,则“git status --ignored path/”不会列出“path”中被忽略的文件和目录。
在遍历引导目录时禁用DIR_SHOW_OTHER_DIRECTORIES标志。这可以防止带有DIR_SHOW_IGNORED标志的treat_leading_path()在顶级未跟踪目录处中止。
作为副作用,这也消除了每个引导目录级别的递归目录扫描,因为当从treat_leading_path()调用时,treat_directory()不能再调用read_directory_recursive()
但是,6年后(2019年底),随着Git 2.25(2020年第一季度),对目录遍历API的各种修复......恢复上面看到的修复,并重新实现它。
参见commit 6836d2f(2019年12月20日),作者Junio C Hamano ( gitster )
参见commit c847dfacommit 777b420commit b9670c1(2019年12月19日)和commit c5c4eddcommit 072a231commit 2f5d384commit a2b1336commit 452efd1(2019年12月10日)至Elijah Newren ( newren )
(由Junio C Hamano -- gitster --合并至commit d2189a7,2019年12月25日)

Revert "dir.c:使'git-status --ignored'在引导目录中工作”

签署人:伊莱贾·纽伦
提交be8a84c52669(“[ dir.c ](https://github.com/git/git/blob/a2b13367fe55bdeb10862f41aff3e2446b63e171/dir.c):make ' git-status --ignored ' work within leading directories”,2013-04-15,Git v1.8.3-rc0 -- merge)指出

git status --ignored <SOMEPATH>

如果<SOMEPATH>未被跟踪,则不会列出<SOMEPATH>中被忽略的文件和目录,并修改了行为以显示它们。
然而,它通过一个破坏一致性的黑客做到了这一点;它将显示<SOMEPATH>下的路径,与简单的

git status --ignored | grep <SOMEPATH>

会向他们展示。
正确的修复稍微复杂一些,所以我们恢复这个提交(但保留测试用例的更正版本),稍后将使用后续补丁修复原始错误。
一些历史可能会有所帮助:
commit 48ffef966c76(“ls-files:fix overeager pathspec optimization”,2010-01-08,Git v1.7.0-rc0 -- merge);但实际上是朝着相反的方向。
在那次提交中,它提到了如何

git ls-files -o --exclude-standard t/

用于显示t/下未跟踪的文件,即使t/被忽略,然后更改行为以停止显示忽略目录下未跟踪的文件。
更重要的是,这次提交考虑了保留这个行为,但是注意到当指定了多个路径规范时,它将与行为不一致,因此拒绝了它。
当指定一个路径规范而不是零个或两个路径规范时,整个不一致的原因是因为路径规范的公共前缀通过一组不同的检查(在treat_leading_path()中)发送,而不是正常的文件/目录遍历(通过read_directory_recursive()treat_path())。
因此,为了一致性,需要检查两个代码路径是否产生相同的结果。
恢复commit be8a84c526691667fc04a8241d93a3de1de298ab,除了不删除它添加的测试用例,而是修改它以检查正确和一致的行为。
并且:

dir:修复检查公用前缀目录

签署人:伊莱贾·纽伦
许多年前,目录遍历逻辑有一个优化,它总是递归到所有路径规范的公共前缀的任何目录,而不需要遍历前导目录以到达所需的目录。
因此,

git ls-files -o .git/                        # case A

注意到.git/是所有路径规范的公共前缀(因为它是唯一列出的路径规范),然后遍历它并开始显示该目录下的未知文件。
不幸的是,.git/不是我们应该遍历的目录,这使得这种优化存在问题。
这也影响到以下情况:

git ls-files -o --exclude-standard t/        # case B

其中t/.gitignore文件中,因此不感兴趣,不应该递归到。
它还影响到以下情况:

git ls-files -o --directory untracked_dir/   # case C

其中untracked_dir/确实是未跟踪的,因此很有趣,但是--directory标志意味着我们只想显示目录本身,而不是递归到它并开始列出它下面的未跟踪文件。
在提交16e2cfa90993("read_directory()中记录并修复了案例B类错误:进一步拆分treat_path()“,2010-01-08)和48ffef966c76(“ls-files:fix overeager pathspec optimization”,2010-01-08,Git v1.7.0-rc 0--merge),我们首先要检查公共前缀是否有趣。
前一个补丁指出,在检查公共前缀时不能使用treat_path(),因为treat_path()需要dir_entry(),而我们在检查公共前缀时没有读取任何目录。
因此,该补丁将treat_one_path()treat_path()中分离出来。

后一个补丁随后创建了一个新的treat_leading_path(),它手动复制了treat_path()中无法被打破的位,然后调用treat_one_path()来获得剩余部分。
这种方法有三个问题:

  • treat_leading_path()中的重复逻辑意外地错过了对特殊路径的检查(例如is_dot_or_dotdot和匹配的“.git”),导致情况A类型的错误继续成为一个问题。
  • treat_leading_path()逻辑假设我们应该遍历path_treatment不是path_none的任何东西,即它使C类的bug永久化。
  • 这意味着我们有需要保持同步的分割逻辑,冒着人们引入新的不一致的风险(例如在commit be8a84c52669中,我们在本系列的前面部分恢复了它,或者在commit df5bcdf83ae中,我们将在后续提交中修复它)。

通过使treat_leading_path()不仅在每个前导路径组件上循环,而且直接在每个组件上调用treat_path(),可以修复大多数这些问题。
为此,我们必须创建一个合成的dir_entry,,但这只需要几行代码。
然后,注意我们从treat_path()得到的path_treatment结果,不要将path_excluded,path_untracked,path_recurse都视为path_recurse

pgvzfuti

pgvzfuti8#

您可能会在使用chmod修改的文件中遇到该错误。
使用git status -u,您可以在“未跟踪的文件”中看到它们,但使用git diff,它们都没有显示任何差异。

相关问题