我有一个文件夹结构如下的项目:
所有的项目文件都在base_fldr
文件夹中。另外,我在base_fldr
中有几个文件夹,称为sub_fldr1
和sub_fldr2
。这些子文件夹也包含一些文件。
如果我修改了base_fldr
或base_fldr\sub_fldr\
中的任何文件,那么git status
将显示为已修改。此外,如果我向base_fldr
添加新文件,git status
将显示为未跟踪的文件。
我的问题是,如果我在base_fldr\sub_fldr\
中添加一个新文件,那么git status
不会将该文件显示为未跟踪。它甚至不会给予有关该文件的任何信息。
该文件或其扩展名不在我的.gitignore
列表中。此外,我确实尝试了git add sub_fldr\file_name
,但它既没有给出错误,也没有将该文件添加到索引中。
知道这里发生了什么吗谢谢!
8条答案
按热度按时间jbose2ul1#
我发现了问题所在。基本上我的.gitignore文件的第一行是“*/"。这会导致git status命令忽略任何添加到子目录的文件。但有趣的是,如果我修改子文件夹中的任何文件,git status正确地显示它们已修改,因为文件已经在git仓库中,但忽略子文件夹中的新文件。
我通过删除.gitignore文件中不忽略子文件夹中的更改的行来修复我的问题,然后将新文件添加到索引中,然后再次添加回.gitignore中的行,以便它将忽略子文件夹中的任何生成的文件。
感谢所有的回应。
nsc4cvqm2#
这可能是因为您的base_fldr\sub_fldr\目录未被跟踪,如果您运行:
从您的工作副本根目录中,它将自动添加该目录以及该目录中的其他文件和目录。
默认情况下,git不会显示未被跟踪的目录中的文件。
lfapxunr3#
我遇到了一个类似的问题,丢失的跟踪文件。在尝试管理跟踪文件的本地修改版本而不必经常避免意外提交的方法时,我运行了以下内容:
我最终放弃了这个想法,但忘记了撤销命令,所以对这个和其他--assume-unchanged文件的后续更改完全丢失了:
我花了一段时间才弄清楚发生了什么,但我只需要反转命令:
fiei3ece4#
你的
sub_fldr
目录中是否有一个.git
子目录?Git可能会认为你试图使用submodules。a0x5cqrl5#
为了调试这样的问题,请通过观察以下两个输出来确定您的
.gitignore
文件是否是罪魁祸首参见https://git-scm.com/docs/git-ls-files
git ls-files --other --directory --exclude-standard
这将显示所有未跟踪的文件,同时遵守
.gitignore
文件。git ls-files --other --directory
这将显示所有未跟踪的文件,而不遵守
.gitignore
文件。无论哪个文件出现在
2
的输出中,但不出现在1
的输出中,由于.gitignore
文件中的某些标志,这些文件都不会显示在未跟踪中bqjvbblv6#
下面是问题中描述的另一个原因(git status untracked files list doesn 't include an untracked file in a sub-folder*)。如果文件因为子文件夹中的.gitignore文件 * 而被取消跟踪,那么该文件将不会被包含在git status untracked files list中。
dfty9e197#
自2011年以来,Git v1.8.3-rc 0(2013年4月)首次修复了这一问题。
它修复了代码中的一些问题,以遍历工作树来查找未跟踪和/或忽略的文件,清理和优化代码路径。
参见commit 0aaf62b,commit defd7c7,commit 8aaf8d7,commit b07bc8c,commit 95c6f27,commit 6cd5c58,commit 46aa2f9,commit 5bd8e2d,commit be8a84c,commit c94ab01,commit 184d2a8,commit 0104c9e,commit 289ff55,commit 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 c847dfa、commit 777b420、commit b9670c1(2019年12月19日)和commit c5c4edd、commit 072a231、commit 2f5d384、commit a2b1336、commit 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)指出如果
<SOMEPATH>
未被跟踪,则不会列出<SOMEPATH>
中被忽略的文件和目录,并修改了行为以显示它们。然而,它通过一个破坏一致性的黑客做到了这一点;它将显示
<SOMEPATH>
下的路径,与简单的会向他们展示。
正确的修复稍微复杂一些,所以我们恢复这个提交(但保留测试用例的更正版本),稍后将使用后续补丁修复原始错误。
一些历史可能会有所帮助:
在commit 48ffef966c76(“
ls-files
:fix overeager pathspec optimization”,2010-01-08,Git v1.7.0-rc0 -- merge);但实际上是朝着相反的方向。在那次提交中,它提到了如何
用于显示
t/
下未跟踪的文件,即使t/
被忽略,然后更改行为以停止显示忽略目录下未跟踪的文件。更重要的是,这次提交考虑了保留这个行为,但是注意到当指定了多个路径规范时,它将与行为不一致,因此拒绝了它。
当指定一个路径规范而不是零个或两个路径规范时,整个不一致的原因是因为路径规范的公共前缀通过一组不同的检查(在
treat_leading_path()
中)发送,而不是正常的文件/目录遍历(通过read_directory_recursive()
和treat_path()
)。因此,为了一致性,需要检查两个代码路径是否产生相同的结果。
恢复commit be8a84c526691667fc04a8241d93a3de1de298ab,除了不删除它添加的测试用例,而是修改它以检查正确和一致的行为。
并且:
dir
:修复检查公用前缀目录签署人:伊莱贾·纽伦
许多年前,目录遍历逻辑有一个优化,它总是递归到所有路径规范的公共前缀的任何目录,而不需要遍历前导目录以到达所需的目录。
因此,
注意到
.git/
是所有路径规范的公共前缀(因为它是唯一列出的路径规范),然后遍历它并开始显示该目录下的未知文件。不幸的是,
.git/
不是我们应该遍历的目录,这使得这种优化存在问题。这也影响到以下情况:
其中
t/
在.gitignore
文件中,因此不感兴趣,不应该递归到。它还影响到以下情况:
其中
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永久化。通过使
treat_leading_path()
不仅在每个前导路径组件上循环,而且直接在每个组件上调用treat_path()
,可以修复大多数这些问题。为此,我们必须创建一个合成的
dir_entry,
,但这只需要几行代码。然后,注意我们从
treat_path()
得到的path_treatment
结果,不要将path_excluded,
path_untracked,
和path_recurse
都视为path_recurse
。pgvzfuti8#
您可能会在使用
chmod
修改的文件中遇到该错误。使用
git status -u
,您可以在“未跟踪的文件”中看到它们,但使用git diff
,它们都没有显示任何差异。